一、所需工具
1.任一一个STM32的单片机(这里我用的野火的stm32f429igt6核心板)
2.matlab
二、测试步骤
1.移植ST官方DSP库
(1)首先在官网上下载DSP库(这里是f4的DSP库,f1的有点不一样,f1移植的时候可以参考安富莱的DSP教程)
下不下来就用我这个版本的(可能不是最新版的)
链接:https://pan.baidu.com/s/1nE3VeFIeuw4AwRTuL_swgA
提取码:fklf
(2)移植
首先有个固件库模板,然后将下面两个文件复制到工程的Libraries(也就是放固件库的文件下,其实放哪里都无所谓,只要编译器能找到就行)
这两个文件在下载的ST官方DSP库文件里面:
然后在工程中
最终效果图:
然后像图中蓝色那样Use Single Precision(这样有一点坏处就是所有的小数与小数之间的运算编译器默认会变成double型,所以在精度要求不高的前提下,在小数后面加个f,这样就不会出现Warnning)
然后添加头文件路径
在Define那里添加:__FPU_PRESENT=1,__TARGET_FPU_VFP,ARM_MATH_CM4,__CC_ARM
最后再包含 #include "arm_math.h"
然后测试一下是否可以用
可以清晰的看到当打下arm时,出现了DSP库里面的函数,那么宣告移植成功
2.用matlab设计低通滤波器
(1)这里为了演示如何使用DSP库,将采样频率设计成45K,截止频率为6K,并用matlab生成1K与15K的正弦波数据,将数据放到excel中并作出表
可以看到1K的正弦波中夹杂着15K的谐波
(2)用matlab的fdatool工具设计滤波器
设计完成后:电机Targets,然后Generate C header
然后将生成文件的数据copy到工程的数组里面(这里用的ST官方例程命名)
注意:这里的工程是移植完DSP库的工程,没有移植的话这些滤波函数是无法使用的
3.工程代码(只贴了部分):
#define TEST_LENGTH_SAMPLES 320
#define BLOCK_SIZE 32
#define NUM_TAPS 29
/* -------------------------------------------------------------------
* The input signal and reference output (computed with MATLAB)
* are defined externally in arm_fir_lpf_data.c.
* ------------------------------------------------------------------- */
extern float32_t testInput_f32_1kHz_15kHz[TEST_LENGTH_SAMPLES];
/* -------------------------------------------------------------------
* Declare Test output buffer
* ------------------------------------------------------------------- */
static float32_t testOutput[TEST_LENGTH_SAMPLES];
/* -------------------------------------------------------------------
* Declare State buffer of size (numTaps + blockSize - 1)
* ------------------------------------------------------------------- */
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];
/* ----------------------------------------------------------------------
** FIR Coefficients buffer generated using fir1() MATLAB function.
** fir1(28, 6/24)
** ------------------------------------------------------------------- */
const float32_t firCoeffs32[NUM_TAPS] = {
-0.001355670276,-0.002235466149,-0.001963305054, 0.001088276156, 0.00700009428,
0.01148389559, 0.007103286684, -0.01001676917, -0.03250513598, -0.04089481756,
-0.01371958014, 0.05627118424, 0.1515145153, 0.2345061451, 0.2674467266,
0.2345061451, 0.1515145153, 0.05627118424, -0.01371958014, -0.04089481756,
-0.03250513598, -0.01001676917, 0.007103286684, 0.01148389559, 0.00700009428,
0.001088276156,-0.001963305054,-0.002235466149,-0.001355670276
};
/* ------------------------------------------------------------------
* Global variables for FIR LPF Example
* ------------------------------------------------------------------- */
uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;
float32_t snr;
/* ----------------------------------------------------------------------
* FIR LPF Example
* ------------------------------------------------------------------- */
int32_t main(void)
{
uint32_t i;
float min,max;
arm_fir_instance_f32 S;
// arm_status status;
float32_t *inputF32, *outputF32;
/* Initialize input and output buffer pointers */
inputF32 = &testInput_f32_1kHz_15kHz[0];
outputF32 = &testOutput[0];
/* Call FIR init function to initialize the instance structure. */
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], blockSize);
Debug_USART_Config();
/* ----------------------------------------------------------------------
** Call the FIR process function for every blockSize samples
** ------------------------------------------------------------------- */
for(i=0; i < numBlocks; i++)
{
arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize);
}
for(i=0;i
printf("%f\r\n",testOutput[i]);
}
通过串口打印出来的数据在excel表格中描点绘制出来
而且是可以清楚地看到一个周期45个点,只剩下了1K的正弦波(瑕疵是前面几个点必须舍去了)
三、同样方法得到的案例
下面是用100K的采样频率采出的信号,1K的信号上面夹杂高次谐波
通过增加滤波器的阶数,滤波后的信号为
遗憾的是也会造成信号的丢失