首先我们打开Matlab。在命令串口输入fdatool,按回车。
Response Type :这里可以设置滤波器类型 lowpass(低通),highpass(高通),banpass(带通),bandstop(带阻)。
Design Method(设计模式):有IIR和FIR两大类。(这里我们用FIR)
Specify order 滤波器的阶数
Window 窗口 这里可以设置滤波器类型。
Units 这里可以设置频率的单位。
Fs 你的采样率。
Fc 截止频率。
点击Design Filter,就会显示出所设计的滤波器。这里我设计的是30阶的低通滤波器,截止频率为125Hz。我们按照下图点击。
按照下图配置,然后点击生成.h文件。
打开文件就可以看到一个数组,这个数组就是stm32dsp库里面要用到的滤波系数。
接下来是stm32的配置。
首先我们先引用dap库。
点击上方的四角形
勾选dsp库,并在main.c添加两个文件。
#include "arm_math.h"
#include "arm_const_structs.h"
在下面添加USE_HAL_DRIVER,STM32F429xx,ARM_MATH_CM4,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING (我用的是f429)
接下来就是stm32的代码部分了,首先先导入滤波系数,将数组改成浮点型。
const int BL = 30;
float B[30] = {
0.0005415165797, 0.001727426774, 0.003113061655, 0.003883380443, 0.002264012117,
-0.003352924949, -0.01260423567, -0.0218139533, -0.02428940125, -0.01267496031,
0.01740843058, 0.06416342407, 0.11868231, 0.1671814919, 0.1957704276,
0.1957704276, 0.1671814919, 0.11868231, 0.06416342407, 0.01740843058,
-0.01267496031, -0.02428940125, -0.0218139533, -0.01260423567,-0.003352924949,
0.002264012117, 0.003883380443, 0.003113061655, 0.001727426774,0.0005415165797
};
按照上面的步骤配置正确,我下面封装的函数是能直接用的。(input,output数组需定义在main函数以外,不让程序会卡死)
void FIR(int Length ,int BLOCK_SIZE ,int BL ,float32_t *input,float32_t *output,float *B)// Length 代表采的点数,BLOCK_SIZE大于1小于你的采样点数即可,BL代表滤波阶数,inout,output,代表输入数据和存储输出数据的数组,B是滤波系数。
{
uint32_t i;
uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = Length /BLOCK_SIZE;
float32_t State[BLOCK_SIZE + BL - 1];
float32_t *inputF32, *outputF32;
arm_fir_instance_f32 S;
inputF32 = &input[0];
outputF32 = &output[0];
arm_fir_init_f32(&S, BL , (float32_t *)&B[0], &State[0], blockSize);
for(int i=0; i < numBlocks; i++)
{
arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize);
}
}
记得在main.h里添加下面的文件,不然会有一大堆报错
下面是我的测试程序,这是通过串口直接给Matlab发送数据并画图,让我们更能直观的看到其滤波效果。具体怎么配置,可以查看我的另一篇文章,超简单的。单片机与matlab之间的串口通信
for(int i=0;i<1000;i++)
{
input[i]=sin(2*i*PI*5/1000)+sin(2*i*PI*200/1000);//5hz和200hz的正弦波信号
}
while (1)
{
FIR(1000,100,30,input,output,B);
HAL_UART_Receive_IT(&huart1,(uint8_t*)aRxBuffer,1);// 串口持续接受信号
// printf("%d\r\n",aRxBuffer[0]);
if(aRxBuffer[0]==100)// 判断握手信号是否到来
{
for(int i=0;i<1000;i++)
{
D_data.data=output[i];//将数据赋给共同体
HAL_UART_Transmit(&huart1,D_data.ComInfo.com, 4, 0xffff);//将4个字节发送出去
HAL_Delay(5);
}
aRxBuffer[0]=1;// 清空标志位
}
}
将D_data.data=output[i];改成D_data.data=input[i],在运行一次Matlab的程序,就可以得到一张很直观的图。下面是我测试的效果,红色的是200Hz的和5hz叠加正弦信号,蓝色的是滤波后的信号,滤波效果还是不错的。
创造不易,感谢关注与点赞。