安裝
參考:
【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/逆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表示啟用位反轉 |
幅度計算
// 計算復數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);