使用MATLAB和DSP官方库完成8阶椭圆滤波

目录

1.IIR滤波器介绍

2. Matlab工具箱filterDesigner生成IIR8阶椭圆滤波器系数

3.DSP库的安装使用

4.具体使用示例

函数 arm_biquad_cascade_df1_init_f32

函数 arm_biquad_cascade_df1_f32

IIR滤波器与DSP库结合使用


1.IIR滤波器介绍

ARM官方提供的直接I型IIR库支持Q7,Q15,Q31和浮点四种数据类型。其中Q15和Q31提供了快速版本。

直接I型IIR滤波器是基于二阶Biquad级联的方式来实现的。每个Biquad由一个二阶的滤波器组成:

y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]

直接I型算法每个阶段需要5个系数和4个状态变量。

这里有一点要特别的注意,有些滤波器系数生成工具是采用的下面公式实现:

y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]

比如matlab就是使用上面的公式实现的,所以在使用fdatool工具箱生成的a系数需要取反才能用于直接I型IIR滤波器的函数中。

高阶IIR滤波器的实现是采用二阶Biquad级联的方式来实现的。其中参数numStages就是用来做指定二阶Biquad的个数。比如8阶IIR滤波器就可以采用numStages=4个二阶Biquad来实现。

如果要实现9阶IIR滤波器就需要将numStages=5,这时就需要其中一个Biquad配置成一阶滤波器(也就是b2=0,a2=0)。
 

2. Matlab工具箱filterDesigner生成IIR8阶椭圆滤波器系数

下面我们讲解如何通过filterDesigner工具箱生成滤波器系数。首先在matlab的命令窗口输入filterDesigner就能打开这个工具箱(电脑没有matlab也可以使用网页版的,本人用的就是网页版的):

filterDesigner界面打开效果如下:

我们需要的截止频率为10hz,采样率为250HZ,设置如下

默认生成的 IIR 滤波器类型是 Direct-Form II, Second-Order Sections(直接 II 型,每个
Section 是一个 二阶滤波器)。这里我们需要将其转换成Direct-Form I, Second-Order
Sections,因为本章使用的IIR滤波器函数是Direct-Form I的结构。 转换方法:点击 Edit->Convert
Structure,界面如下,这里我们选择第一项,并点击 OK:

转换好以后再点击 File-Export,第一项选择 Coefficient File(ASCII):

第一项选择好以后,第二项选择Decimal:

两个选项都选择好以后,点击 Export 进行导出,导出后保存即可。

保存后Matlab会自动打开untitled.fcf文件,可以看到生成的系数

由于前面选择的是8阶IIR滤波,生成的结果就是由4组二阶IIR滤波系数组成,系数的对应顺序如下:

由于Matlab设计IIR所使用的公式与DSP库函数中有所不同,故需对系数的处理:去掉每行的a0,并把a1,a2取反。经过处理后的系数才可与DSP库结合使用,另外下面4组是每个二阶滤波器的增益,滤波后的结果要乘以这4个增益数值才是实际结果:

0.608551805262785516781320893642259761691  

0.420200533983016655259490335083683021367   

0.188703183637426996632768805284285917878   

0.008371840872980450265483653993214829825

实际的滤波系数调用方法,看下面的例子即可

3.DSP库的安装使用

通过GitHub下载,地址:GitHub - ARM-software/CMSIS_5: CMSIS Version 5 Development Repository 

4.具体使用示例

函数 arm_biquad_cascade_df1_init_f32

void arm_biquad_cascade_df1_init_f32(
 arm_biquad_casd_df1_inst_f32 * S,
 uint8_t numStages,
 const float32_t * pCoeffs,
 float32_t * pState);
  • 函数描述:
    这个函数用于 IIR 初始化。
  • 函数参数:
    ◆ 第 1 个参数是 arm_biquad_casd_df1_inst_f32 类型结构体变量。
    ◆ 第 2 个参数是 2 阶滤波器的个数。
    ◆ 第 3 个参数是滤波器系数地址。
    ◆ 第 4 个参数是缓冲状态地址

函数 arm_biquad_cascade_df1_f32

  • 函数原型:
  •  void arm_biquad_cascade_df1_f32(
     const arm_biquad_casd_df1_inst_f32 * S,
     float32_t * pSrc,
     float32_t * pDst,
     uint32_t blockSize);
    

    函数描述:
    这个函数用于 IIR 滤波。
    函数参数:
    ◆ 第 1 个参数是 arm_biquad_casd_df1_inst_f32 类型结构体变量。
    ◆ 第 2 个参数是源数据地址。
    ◆ 第 3 个参数是滤波后的数据地址。
    ◆ 第 4 个参数是每次调用处理的数据个数,最小可以每次处理 1 个数据,最大可以每次全部处理完。

  • IIR滤波器与DSP库结合使用

  • /*
     * @Descripttion: main
     * @Author: Cheng
     * @Date: 2024-05-08 14:06:15
     * @LastEditTime: 2024-05-08 14:06:15
     *
     * Copyright 2024
     */
    
    #include "main.h"
    #include "arm_math.h"
    extern uint8_t read_flag;
    /*!
    	\brief      main function
    	\param[in]  none
    	\param[out] none
    	\retval     none
    */
    static FilterState x_filter_state;
    static FilterState y_filter_state;
    static FilterState z_filter_state;
    
    
    /*% 离散时间 IIR 滤波器(实数)                                                                                                                        
    % ----------------                                                                                                                        
    % 滤波器结构  : 直接 I 型,二阶节                                                                                                                     
    % 节数     : 4                                                                                                                              
    % 稳定     : 是                                                                                                                              
    % 线性相位   : 否                                                                                                                              
    
                                                                                                                                             
    SOS 矩阵:   
    b0  b1                                         b2 a0  a1                                         a2
    1  -1.871329986332524564218715568131301552057  1  1  -1.883217591080840414008434891002252697945  0.937253227826082335738533402036409825087
    1  -1.763596688085204311491338557971175760031  1  1  -1.841349414704919640328739660617429763079  0.874973529167388908156510751723544672132
    1  -0.764306729111819960209572855092119425535  1  1  -1.803936748444220583564856497105211019516  0.817480187395823065799049800261855125427
    1  -1.896005581016128482829685708566103130579  1  1  -1.916868836897071881608667354157660156488  0.981783959561862595855075142026180401444
       
    	 注意,实际使用ARM官方的IIR函数调用的时候要将a1和a2取反,a0不要。另外下面4组是每个二阶滤波器的增益,滤波后的结果要乘以这4个增益数值才是实际结果:	 
    定标值:                                                                                                                                      
    0.608551805262785516781320893642259761691                                                                                                 
    0.420200533983016655259490335083683021367                                                                                                 
    0.188703183637426996632768805284285917878                                                                                                 
    0.008371840872980450265483653993214829825                                                                                                 
    */
    
    // 定义滤波器系数
    #define FILTER_ORDER 8
    #define NUM_STAGES (FILTER_ORDER / 2)
    
    const float32_t sos_coeffs[NUM_STAGES * 5] = {
        1.0f, -1.871329986332524564218715568131301552057, 1.0f, 
    		1.883217591080840414008434891002252697945,-0.937253227826082335738533402036409825087,
    	
    		1.0f, -1.763596688085204311491338557971175760031,1.0f,  
    		1.841349414704919640328739660617429763079, -0.874973529167388908156510751723544672132,
    	
    		1.0f, -0.764306729111819960209572855092119425535, 1.0f,  
    		1.803936748444220583564856497105211019516, -0.817480187395823065799049800261855125427,
    	
    		1.0f, -1.896005581016128482829685708566103130579, 1.0f,
    	  1.916868836897071881608667354157660156488, -0.981783959561862595855075142026180401444
        
    	
    };
    
    float32_t IIRState[4 * NUM_STAGES];
    
    
    
    int main(void)
    {
    	static uint8_t data_ready_flag = 0;
    	static float x_measure_data = 0;
    	static float y_measure_data = 0;
    	static float z_measure_data = 0;
    	static float xfiltered, yfiltered, zfiltered;
    	static int initialized = 0; 
    	float32_t ScaleValue=(0.608551805262785516781320893642259761691f*0.420200533983016655259490335083683021367f*
    	0.188703183637426996632768805284285917878f*0.008371840872980450265483653993214829825f);
    	systick_config();
    	Uart_Printf_Init();
    	// 定义滤波器实例
       arm_biquad_casd_df1_inst_f32 S;
    	// 初始化滤波器系数
      
    	// 初始化滤波器结构
      //arm_biquad_cascade_df2T_init_f32(&S, NUM_STAGES, biquadCoeffs, biquadState);
    	arm_biquad_cascade_df1_init_f32(&S, NUM_STAGES, (float32_t *)&sos_coeffs[0], (float32_t *)&IIRState[0]);
    	while (1)
    	{
    		if (read_flag)
    		{
    			x_measure_data = ((measure_data.x_data) / adxl355Scale);
    			y_measure_data = ((measure_data.y_data) / adxl355Scale);
    			z_measure_data = ((measure_data.z_data) / adxl355Scale) - 1;
    
    		 // 应用滤波器
    			arm_biquad_cascade_df1_f32(&S, &x_measure_data, &xfiltered, 1);
    			arm_biquad_cascade_df1_f32(&S, &y_measure_data, &yfiltered, 1);
    			arm_biquad_cascade_df1_f32(&S, &z_measure_data, &zfiltered, 1);
    			//arm_biquad_cascade_df2T_f32(&S, &z_measure_data, &zfiltered, 1);
    			printf("\r\nacceleration data:%.4f,%.4f,%.4f\r\n", x_measure_data, y_measure_data, z_measure_data);
    			printf("\r\n filter acceleration data:%.4f,%.4f,%.4f\r\n", xfiltered*ScaleValue, yfiltered*ScaleValue, zfiltered*ScaleValue);
    			read_flag = 0;
    		}
    	}
    }
    
  • 更新:注意本例程对x,y,z三轴数据进行滤波,则float32_t IIRState[4 * NUM_STAGES];和arm_biquad_casd_df1_inst_f32 S;

  • 需要三个不同的定义:

  • float32_t IIRStateX[4 * NUM_STAGES];arm_biquad_casd_df1_inst_f32 SX;

  • float32_t IIRStateY[4 * NUM_STAGES];arm_biquad_casd_df1_inst_f32 SY;

  • float32_t IIRStateZ[4 * NUM_STAGES];arm_biquad_casd_df1_inst_f32 SZ;

  • 否则会造成滤波数据有错

  • 参考:【STM32H7的DSP教程】第6章 ARM DSP源码和库移植方法(MDK5的AC5和AC6)_arm移植dsp库-CSDN博客
    【STM32F429的DSP教程】第44章 STM32F429的IIR低通滤波器实现(支持逐个数据的实时滤波)_低通滤波 实时-CSDN博客
    【电赛仪器仪表】基于MATLAB的数字滤波器设计与ARM官方DSP库的结合_基于stm32f10x的fir滤波器设计与实现-CSDN博客

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值