STM32CubeMX+CLion 使用ARM_CMSIS_DSP_arm.cmsis-dsp
安装
参考:
【CLion开发stm32】如何使用DSP库 - 未知的奇迹 - 博客园
实际上这样配置会出一点小问题,现对其修改
1. 项目根目录下新建 DSP_LIB文件夹
将目录STM32CubeMX\\Repository\\STM32Cube_FW_G4_V1.6.1\\Drivers\\CMSIS\\DSP下的Include文件夹和Sources文件夹复制到DSP_LIB文件夹中
在Include文件夹中,仅保留arm_common_tables.h,arm_const_structs.h,arm_math.h三个头文件,删除其余头文件。
如果没有,需要在Software Packs里下载
2. 修改CMakeLists_template.txt文件内容为
include_directories(${includes} DSP_LIB/Include)add_definitions(${defines})file(GLOB_RECURSE SOURCES ${sources} \"DSP_LIB/Source/*.c\")list(FILTER SOURCES EXCLUDE REGEX \".*/arm_.*\\\\.c\")
3. 点击STM32CubeMX中的 GENERATE CODE 重新生成代码
常用函数讲解
两种类型:
- 浮点类型:
- 定点类型
基本数学运算
// 浮点加法float32_t arm_add_f32(float32_t a, float32_t b);// 浮点乘法float32_t arm_mult_f32(float32_t a, float32_t b);// 浮点向量加法(逐个元素相加)void arm_add_f32(const float32_t *pSrcA, const float32_t *pSrcB, float32_t *pDst, uint32_t blockSize);// 浮点向量乘法(逐个元素相乘)void arm_mult_f32(const float32_t *pSrcA, const float32_t *pSrcB, float32_t *pDst, uint32_t blockSize);// Q15加法q15_t arm_add_q15(q15_t a, q15_t b);// Q15乘法q15_t arm_mult_q15(q15_t a, q15_t b);// Q31乘法q31_t arm_mult_q31(q31_t a, q31_t b);
参数解释:
- const float32_t *pSrcA:第一个输入数组指针
- const float32_t *pSrcB:第二个输入数组指针
- float32_t *pDst:输出数组指针
- uint32_t blockSize:数组元素个数
快速傅里叶变换(FFT)函数
初始化实例
// 初始化浮点FFT实例arm_status arm_cfft_init_f32(arm_cfft_instance_f32 *S, uint16_t fftLen);// 初始化Q15 FFT实例arm_status arm_cfft_init_q15(arm_cfft_instance_q15 *S, uint16_t fftLen);
参数解释:
- arm_cfft_instance_f32 *S:FFT实例结构体指针
- uint16_t fftLen:FFT长度(点数)
- arm_cfft_sR_f32_lenx,x可取大于等于16的2的整数幂,例如 arm_cfft_sR_f32_len16、arm_cfft_sR_f32_len32等
使用预定义的初始化方法:
const arm_cfft_instance_f32 *fftInstance = &arm_cfft_sR_f32_len256;
核心函数
// 浮点复数FFT/逆FFTvoid arm_cfft_f32(const arm_cfft_instance_f32 *S, float32_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag);// Q15复数FFT/逆FFTvoid arm_cfft_q15(const arm_cfft_instance_q15 *S, q15_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag);
参数解释
S
arm_cfft_init_f32
或预定义实例提供)p1
ifftFlag
bitReverseFlag
幅度计算
// 计算复数FFT结果的幅度(浮点)void arm_cmplx_mag_f32(float32_t *pSrc, float32_t *pDst, uint32_t numSamples);// 计算复数FFT结果的幅度(Q15)void arm_cmplx_mag_q15(q15_t *pSrc, q15_t *pDst, uint32_t numSamples);
参数解释
- pSrc:FFT复数结果
- pDst:幅度谱
- numSamples:样本数量
滤波器函数
FIR滤波器
// 浮点FIR初始化void arm_fir_init_f32(arm_fir_instance_f32 *S, uint16_t numTaps, float32_t *pCoeffs, float32_t *pState, uint32_t blockSize);// Q15 FIR初始化void arm_fir_init_q15(arm_fir_instance_q15 *S, uint16_t numTaps, q15_t *pCoeffs, q15_t *pState, uint32_t blockSize);
参数解释
- arm_fir_instance_f32 *S:FIR滤波器实例指针
- uint16_t numTaps:滤波器系数个数
- float32_t *pCoeffs:滤波器系数数组指针
- float32_t *pState:状态缓冲区指针
- uint32_t blockSize:每次处理的样本块大小
// 浮点FIR滤波void arm_fir_f32(const arm_fir_instance_f32 *S, float32_t *pSrc, float32_t *pDst, uint32_t blockSize);
参数解释:
S
arm_fir_init_f32
初始化的FIR实例pSrc
blockSize
pDst
blockSize
blockSize
IIR滤波器
// 浮点IIR初始化void arm_biquad_cascade_df1_init_f32(arm_biquad_casd_df1_inst_f32 *S, uint8_t numStages, float32_t *pCoeffs, float32_t *pState);// 浮点IIR滤波void arm_biquad_cascade_df1_f32(const arm_biquad_casd_df1_inst_f32 *S, float32_t *pSrc, float32_t *pDst, uint32_t blockSize);
参数解释:
*S
numStages
*pCoeffs
[b0, b1, b2, a1, a2]
顺序排列,每组对应一个阶段,连续存储。*pState
x[n-1]
, y[n-1]
等),大小需为 2 × numStages
。FIR滤波器和IIR滤波器的区别
特性 FIR滤波器 IIR滤波器 全称 Finite Impulse Response Infinite Impulse Response 定义 系统冲激响应在有限时间内衰减为零 系统冲激响应理论上会无限持续 差分方程 仅使用输入信号的历史值 同时使用输入和输出的历史值 数学表达式 y[n] = Σ bₖ·x[n-k] (k=0 to N-1) y[n] = Σ bₖ·x[n-k] - Σ aₖ·y[n-k]
统计函数
// 求最大值及其索引void arm_max_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult, uint32_t *pIndex);// 求最小值及其索引void arm_min_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult, uint32_t *pIndex);// 求平均值void arm_mean_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult);// 求均方根(RMS)void arm_rms_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult);// 求标准差void arm_std_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult);// 求方差void arm_var_f32(float32_t *pSrc, uint32_t blockSize, float32_t *pResult);
矩阵运算函数
// 矩阵加法arm_status arm_mat_add_f32(const arm_matrix_instance_f32 *pSrcA, const arm_matrix_instance_f32 *pSrcB, arm_matrix_instance_f32 *pDst);// 矩阵乘法arm_status arm_mat_mult_f32(const arm_matrix_instance_f32 *pSrcA, const arm_matrix_instance_f32 *pSrcB, arm_matrix_instance_f32 *pDst);// 矩阵转置arm_status arm_mat_trans_f32(const arm_matrix_instance_f32 *pSrc, arm_matrix_instance_f32 *pDst);// 矩阵求逆arm_status arm_mat_inverse_f32(const arm_matrix_instance_f32 *pSrc, arm_matrix_instance_f32 *pDst);
经典数学函数
// 正弦函数(浮点)float32_t arm_sin_f32(float32_t x);// 余弦函数(浮点)float32_t arm_cos_f32(float32_t x);// 平方根void arm_sqrt_f32(float32_t in, float32_t *pOut);
类型转换函数
// 浮点到Q15转换void arm_float_to_q15(float32_t *pSrc, q15_t *pDst, uint32_t blockSize);// Q15到浮点转换void arm_q15_to_float(q15_t *pSrc, float32_t *pDst, uint32_t blockSize);