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

 

然后在工程中

最终效果图:

 

然后像图中蓝色那样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<TEST_LENGTH_SAMPLES;i++)
  {
    printf("%f\r\n",testOutput[i]);
  }

通过串口打印出来的数据在excel表格中描点绘制出来

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

三、同样方法得到的案例

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

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

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

  • 6
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GallagherZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值