用ST官方自带DSP库实现低通滤波

一、所需工具

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库文件里面:

用ST官方自带DSP库实现低通滤波_第1张图片

 

用ST官方自带DSP库实现低通滤波_第2张图片

然后在工程中

用ST官方自带DSP库实现低通滤波_第3张图片

用ST官方自带DSP库实现低通滤波_第4张图片

最终效果图:

用ST官方自带DSP库实现低通滤波_第5张图片

 

然后像图中蓝色那样Use Single Precision(这样有一点坏处就是所有的小数与小数之间的运算编译器默认会变成double型,所以在精度要求不高的前提下,在小数后面加个f,这样就不会出现Warnning)

用ST官方自带DSP库实现低通滤波_第6张图片

然后添加头文件路径

用ST官方自带DSP库实现低通滤波_第7张图片

在Define那里添加:__FPU_PRESENT=1,__TARGET_FPU_VFP,ARM_MATH_CM4,__CC_ARM

用ST官方自带DSP库实现低通滤波_第8张图片

最后再包含  #include "arm_math.h"

然后测试一下是否可以用

用ST官方自带DSP库实现低通滤波_第9张图片

可以清晰的看到当打下arm时,出现了DSP库里面的函数,那么宣告移植成功

 

2.用matlab设计低通滤波器

(1)这里为了演示如何使用DSP库,将采样频率设计成45K,截止频率为6K,并用matlab生成1K与15K的正弦波数据,将数据放到excel中并作出表

用ST官方自带DSP库实现低通滤波_第10张图片

可以看到1K的正弦波中夹杂着15K的谐波

(2)用matlab的fdatool工具设计滤波器

用ST官方自带DSP库实现低通滤波_第11张图片

设计完成后:电机Targets,然后Generate C header

用ST官方自带DSP库实现低通滤波_第12张图片

然后将生成文件的数据copy到工程的数组里面(这里用的ST官方例程命名)

用ST官方自带DSP库实现低通滤波_第13张图片

注意:这里的工程是移植完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表格中描点绘制出来

用ST官方自带DSP库实现低通滤波_第14张图片

而且是可以清楚地看到一个周期45个点,只剩下了1K的正弦波(瑕疵是前面几个点必须舍去了)

三、同样方法得到的案例

下面是用100K的采样频率采出的信号,1K的信号上面夹杂高次谐波

用ST官方自带DSP库实现低通滤波_第15张图片

通过增加滤波器的阶数,滤波后的信号为

用ST官方自带DSP库实现低通滤波_第16张图片

遗憾的是也会造成信号的丢失

你可能感兴趣的:(信号处理)