【STM32 系列】利用MATLAB配合ARM-DSP庫設計FIR數字濾波器(保姆級教程)
ps.源碼放在最后面
設計IIR數字濾波器可以看這里:利用MATLAB配合ARM-DSP庫設計IIR數字濾波器(保姆級教程)
引言
本篇文章將介紹如何利用MATLAB與STM32的ARM-DSP庫相結合,簡明易懂地實現FIR低通濾波器的設計與應用。文章重點不在于理論深度,而是幫助初學者通過實際操作,掌握數字濾波器的實現流程,為后續深入學習打下基礎。
理論基礎
詳看上一篇文章:數字濾波器的分類
設計FIR低通濾波器
MATLAB配置
filterDesigner濾波器設計工具
首先在命令行窗口輸入"filterDesigner",接著就會跳出以下界面:

設計步驟
跟著下圖步驟選擇:

濾波器幅頻響應圖像
接著就可得到以下FIR濾波器及其幅頻響應圖像:

導出濾波器系數
根據以下步驟,導出MATLAB濾波器的系數:
目標"->"生成C頭文件",打開所生成的.h文件,將文件中數組的元素復制下來,后面將其粘貼到代碼中即可。
STM32部分
DSP庫添加
詳細請看硬漢哥的這篇文章,講的十分清晰:ARM DSP源碼和庫移植方法(MDK5的AC5和AC6)
FIR代碼部分
變量參數定義
以下就是需要的變量參數定義,值得注意的是,圖中圈起來的兩個部分,在FIR濾波器發生變化的時候,即參數改變的時候需要修改的參數:

FIR濾波主要代碼

代碼部分沒什么好說的,千篇一律,主要就是MATLAB中生成的濾波器參數不一樣。更換不同的FIR濾波器的時候,將代碼中的濾波器參數和數組大小改一下就行。
程序現象
使用串口打印到VOFA+這個軟件上
信號頻率:4500Hz
采樣頻率:48000Hz
通帶頻率:4000Hz
阻帶頻率:5000Hz
紅色:原始信號波形
綠色:濾波后信號波形

源碼
變量定義部分
/*********************** FIR ***********************/ /** 采樣頻率:48kHz 通帶頻率:4kHz 阻帶頻率:5kHz **/ #define FIR_LENGTH 256 /* FIR濾波器輸入輸出數據的長度 */ #define FIR_NUMTAPS_LENGTH 98 /* FIR濾波器的系數個數 */ #define FIR_PSTATE_LENGTH (FIR_LENGTH + FIR_NUMTAPS_LENGTH - 1) /* FIR濾波器狀態變量的長度 */
arm_fir_instance_f32 * fir_S; /* FIR實例化結構體 /
float32_t FIR_InputBufer[FIR_LENGTH] = {0}; / 輸入數據緩沖區,長度為 FIR_LENGTH /
float32_t FIR_OutputBufer[FIR_LENGTH] = {0}; / 輸出數據緩沖區,長度為 FIR_LENGTH /
uint16_t fir_numTaps = FIR_NUMTAPS_LENGTH; / FIR濾波器系數個數 /
uint32_t fir_blockSize = FIR_LENGTH; / 塊處理大小 /
float32_t fir_pState[FIR_PSTATE_LENGTH] = {0.0f}; / FIR濾波器狀態變量暫存數組:狀態數組的大小為 fir_numTaps + fir_blockSize - 1 /
const float32_t fir_pCoeffs[FIR_NUMTAPS_LENGTH] = { / FIR濾波器系數數組,長度為 FIR_NUMTAPS_LENGTH */
-0.00078254311335225067f, -0.00194089034910090554f, -0.00313185282559110684f, -0.00495539876517352672f,
-0.00638956086602692451f, -0.00757987454003869986f, -0.00772155390280845032f, -0.00687095084055358400f,
-0.00476900664053667676f, -0.00188692319952501889f, 0.00134417816349838314f, 0.00407555838576917698f,
0.00566532906664842656f, 0.00556431360122016001f, 0.00374928839584976175f, 0.00060987014721678768f,
-0.00296735404678587613f, -0.00591985213343452707f, -0.00723224215293890964f, -0.00632349600819474313f,
-0.00323442690521178432f, 0.00127132144860143200f, 0.00589453667352991990f, 0.00912956175478252599f,
0.00974387808929712967f, 0.00719961710314756358f, 0.00192723328839332114f, -0.00469422256804760251f,
-0.01065481062891286343f, -0.01388627358340486194f, -0.01292296778433829618f, -0.00746430826262267644f,
0.00136126826115418606f, 0.01114780347633200115f, 0.01879006594120128520f, 0.02136402303334635974f,
0.01708251376049307185f, 0.00604552989247455347f, -0.00945856323233184963f, -0.02524803257338050638f,
-0.03611715784341684721f, -0.03710298030813360959f, -0.02483745200229213815f, 0.00137548734160661008f,
0.03906511682715284317f, 0.08285990139574969660f, 0.12549091009382731809f, 0.15931768100861251614f,
0.17801724820473396882f, 0.17801724820473396882f, 0.15931768100861251614f, 0.12549091009382731809f,
0.08285990139574969660f, 0.03906511682715284317f, 0.00137548734160661008f, -0.02483745200229213815f,
-0.03710298030813360959f, -0.03611715784341684721f, -0.02524803257338050638f, -0.00945856323233184963f,
0.00604552989247455347f, 0.01708251376049307185f, 0.02136402303334635974f, 0.01879006594120128520f,
0.01114780347633200115f, 0.00136126826115418606f, -0.00746430826262267644f, -0.01292296778433829618f,
-0.01388627358340486194f, -0.01065481062891286343f, -0.00469422256804760251f, 0.00192723328839332114f,
0.00719961710314756358f, 0.00974387808929712967f, 0.00912956175478252599f, 0.00589453667352991990f,
0.00127132144860143200f, -0.00323442690521178432f, -0.00632349600819474313f, -0.00723224215293890964f,
-0.00591985213343452707f, -0.00296735404678587613f, 0.00060987014721678768f, 0.00374928839584976175f,
0.00556431360122016001f, 0.00566532906664842656f, 0.00407555838576917698f, 0.00134417816349838314f,
-0.00188692319952501889f, -0.00476900664053667676f, -0.00687095084055358400f, -0.00772155390280845032f,
-0.00757987454003869986f, -0.00638956086602692451f, -0.00495539876517352672f, -0.00313185282559110684f,
-0.00194089034910090554f, -0.00078254311335225067f
};
主要程序部分
/*********************** FIR濾波 ***********************/
if(filter_Flag == 0){
for (uint16_t i = 0; i < FIR_LENGTH; i++) {
FIR_InputBufer[i] = (float)ADC_DMA_ConvertedValue[i] * 3.3 / 65536.0;
}
/* 為FIR實例分配內存 */
fir_S = (arm_fir_instance_f32 *)malloc(sizeof(arm_fir_instance_f32));
if (fir_S == NULL) {
return 0; /* 內存分配失敗,處理錯誤 */
}
rm_fir_init_f32(fir_S,fir_numTaps,fir_pCoeffs,fir_pState,fir_blockSize);
arm_fir_f32(fir_S,FIR_InputBufer,FIR_OutputBufer,fir_blockSize);
Set_Current_USART(USART1_IDX);/* 使用串口1 */
for (uint16_t i = 49; i < FIR_LENGTH; i++){
printf("%d: %lf,%lf\r\n",i,FIR_InputBufer[i],FIR_OutputBufer[i]);
}
free(fir_S); /* 釋放內存 */
fir_S = NULL; /* 將指針設置為 NULL,以避免懸掛指針 */
}
/*******************************************************/
博客導航
本文來自博客園,作者:膝蓋中箭衛兵,轉載請注明原文鏈接:http://www.rzrgm.cn/Skyrim-sssuuu/p/18774935

浙公網安備 33010602011771號
https://orcid.org/0000-0001-5102-772X