STM32CubeMX+CLion 使用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.harm_const_structs.harm_math.h三个头文件,删除其余头文件。

如果没有,需要在Software Packs里下载

  1. 修改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")

  2. 点击STM32CubeMX中的 GENERATE CODE 重新生成代码

常用函数讲解

两种类型:

  • 浮点类型:
  • 定点类型

基本数学运算

cpp 复制代码
// 浮点加法
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)函数

初始化实例

cpp 复制代码
// 初始化浮点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等

使用预定义的初始化方法:

cpp 复制代码
const arm_cfft_instance_f32 *fftInstance = &arm_cfft_sR_f32_len256;

核心函数

cpp 复制代码
// 浮点复数FFT/逆FFT
void arm_cfft_f32(const arm_cfft_instance_f32 *S, float32_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag);
// Q15复数FFT/逆FFT
void arm_cfft_q15(const arm_cfft_instance_q15 *S, q15_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag);

参数解释

参数 描述
S 预初始化的FFT实例指针(由arm_cfft_init_f32或预定义实例提供)
p1 复数输入/输出数组(实部和虚部交错存储,长度为2*fftlen)
ifftFlag 0表示FFT(正变换),1表示IFFT(逆变换)
bitReverseFlag 0表示禁用位反转,1表示启用位反转

幅度计算

cpp 复制代码
// 计算复数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滤波器

cpp 复制代码
// 浮点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:每次处理的样本块大小
cpp 复制代码
// 浮点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滤波器

cpp 复制代码
// 浮点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]

统计函数

cpp 复制代码
// 求最大值及其索引
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);

矩阵运算函数

cpp 复制代码
// 矩阵加法
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);

经典数学函数

cpp 复制代码
// 正弦函数(浮点)
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);

类型转换函数

cpp 复制代码
// 浮点到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);
相关推荐
cici158741 天前
基于RT-Thread的数字焊机与工业机器人通信网关设计
arm开发·机器人
陌上花开缓缓归以1 天前
rk3568 mmc 驱动之u-boot代码分析
arm开发
EnglishJun1 天前
ARM嵌入式学习(十三)--- IMX6ULL串口
arm开发·学习
CinzWS2 天前
中断向量表中断号与 CMSIS IRQn 映射关系深度剖析:从硬件索引到软件句柄的桥梁
arm开发·架构·系统架构·嵌入式·cortex-m3·中断
FPGA-ADDA3 天前
第一篇:从“软件无线电”到“单芯片无线电”——RFSoC如何重塑无线系统设计
arm开发·信号处理·fpga·通信系统·rfsoc
若风的雨3 天前
【deepseek】ARM TrustZone 架构安全机制
arm开发·安全·架构
Juicedata3 天前
ARM 架构 JuiceFS 性能优化:基于 MLPerf 的实践与调优
arm开发·性能优化·架构
-Try hard-3 天前
ARM | 让蜂鸣器发声!
arm开发
somi73 天前
ARM-07-i.MX6ULL-EPIT定时器和GPT
arm开发·单片机·嵌入式硬件·gpt·定时器·自用·时钟配置
皮皮哎哟3 天前
ARM—点灯(基于正点原子的IMX6U-mini)
arm开发·单片机·嵌入式硬件·imx6ull·点灯·固件库