1,电赛进行时......(DSP中各滤波算法的实现结合Matlab)


前言

长风破浪会有时!直挂云帆济沧海!


一、实现Stm32中Dsp库的低通滤波实现(FIR)

在做心率血氧项目中直接采集到的信号十分毛刺(效果图1-1如下),然而频率在5Hz附近。决定使用低通滤波试试!!!
图片1-1(血氧初始信号)
图片1-1(血氧信号)

实现步骤

1.要实现滤波,需要有参数实现,参数可以从Matlab中获取!!!

a.在命令窗口输入 filterDesigner(会弹出FIR设计工具)

在这里插入图片描述

b.函数原型需要的参数

在这里插入图片描述

c.实现步骤(matlab参数获取 )

matlab参数获取
在这里插入图片描述

d.实现步骤(matlab生成参数 )
以上步骤完成后…点击设计滤波器(截至频率选取50hz左右效果明显)–>点击目标–>选择导出为(我选的是单精度浮点数)–>点击生成 -->保存文件路径

在这里插入图片描述

2.实现滤波在stm32上的滤波器设计

生成的头文件内容

在这里插入图片描述

a.直接上代码

#include "myFIR.h"
#include "arm_math.h"
#include "stdio.h"


uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES / BLOCK_SIZE; 		/* 需要调用arm_fir_f32的次数 */


float32_t testInput_f32_500Hz[TEST_LENGTH_SAMPLES]; 			/* 采样点 */
float32_t testOutput[TEST_LENGTH_SAMPLES]; 							/* 滤波后的输出 */
float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];			 	/* 状态缓存,大小numTaps + blockSize - 1*/


/* 低通滤波器系数 通过fadtool获取*/
const float32_t firCoeffs32LP[29] =
{
     -0.001647398574,-0.0008258497692, 0.001227202825, 0.004726920277, 0.007672414649,
   0.005805777851,-0.004334676079, -0.02075286396, -0.03350708634, -0.02770185284,
   0.008254308254,   0.0736207068,   0.1517520398,   0.2155939639,   0.2402327806,
     0.2155939639,   0.1517520398,   0.0736207068, 0.008254308254, -0.02770185284,
   -0.03350708634, -0.02075286396,-0.004334676079, 0.005805777851, 0.007672414649,
   0.004726920277, 0.001227202825,-0.0008258497692,-0.001647398574
};

void arm_fir_f32_lp(void)
{
    uint32_t i;
    arm_fir_instance_f32 S;
    float32_t* inputF32, *outputF32;
    /* 初始化输入输出缓存指针 */
    inputF32 = &(testInput_f32_500Hz[0]);
    outputF32 = &(testOutput[0]);
    /* 初始化结构体S */
    arm_fir_init_f32(&S,
                     NUM_TAPS,
                     (float32_t*)&firCoeffs32LP[0],
                     &firStateF32[0],
                     blockSize);
    /* 实现FIR滤波,这里每次处理1个点 */
    for(i = 0; i < numBlocks; i++)
    {
        arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize);
    }
}
#ifndef	_MYFIR_H_
#define _MYFIR_H_

#include "main.h"
#include "arm_math.h"

#define TEST_LENGTH_SAMPLES 1024 		/* 采样点数 */
#define BLOCK_SIZE 1 								/* 调用一次arm_fir_f32处理的采样点个数 */
#define NUM_TAPS 29									/* 滤波器系数个数 */


extern float32_t testInput_f32_500Hz[TEST_LENGTH_SAMPLES]; 			/* 采样点 */
extern float32_t testOutput[TEST_LENGTH_SAMPLES]; 							/* 滤波后的输出 */
extern float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];			 	/* 状态缓存,大小numTaps + blockSize - 1*/



void arm_fir_f32_lp(void);


#endif

b.上效果图可以看出毛刺减少了。截至频率选择更小的效果会更好!但是注意不要影响到原信号!!!

原信号
图片1-1(血氧信号)

150hz
在这里插入图片描述
50hz
在这里插入图片描述

		 实现低通,高通,带阻滤波算法也和以上类似!但注意参数的更改!!!       

						完结撒花!!!(没有)

二、实现Stm32中Dsp库的中值滤波实现

以上的低通滤波对于该信号的平滑好像不是那么明显,效果不是很显著!!
那我们就拿出本节讲的中值滤波来试试

1.什么是中值滤波(适用于噪声和脉冲的过滤)

在这里插入图片描述

2.在stm32上实现中值滤波算法(支持数据块和实时数据滤波)

注意:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.实现代码

#define MidFilter_LENGTH_SAMPLES 2048																					/* 采样点数 */
#define MidFilterOrder 16																											  /* 滤波阶数 */
#define ZeroSize        MidFilterOrder

float32_t DstDate[MidFilter_LENGTH_SAMPLES];     													/* 滤波后数据 */
float32_t SortData[MidFilterOrder];  																			/* 滤波排序 */ 
float32_t TempDate[ZeroSize + MidFilter_LENGTH_SAMPLES +ZeroSize] = {0}; /* 滤波阶段用到的临时变量 */


/*
*********************************************************************************************************
*	函 数 名: MidFilterBlock
*	功能说明: 中值滤波器,对一段数据的中值滤波。
*	形    参: 	pSrc 源数据地址。
*             pDst 滤波后数据地址。
*             blockSize 数据个数,至少为2。
*             order 至少2阶。
*	返 回 值: 无
*********************************************************************************************************
*/
void MidFilterBlock(float32_t *pSrc, float32_t *pDst, uint32_t blockSize, uint32_t order)
{
	arm_sort_instance_f32 S;
	uint32_t N, i;
	
	
	S.dir = ARM_SORT_ASCENDING;
	S.alg = ARM_SORT_QUICK;
	
	
	N = order / 2;
	
	/* 数据幅值给临时缓冲 */
	for(i =0; i < blockSize; i++)
	{
		TempDate[i + ZeroSize] = pSrc[i];
	}
	
	
	/* 求每个数据点的中值 */
	for(i =0; i < blockSize; i++)
	{
		/* 排序 */
		arm_sort_f32(&S, &TempDate[i + ZeroSize - N], &SortData[0], order);
		
		/* 奇数 */
		if(N)
		{
			pDst[i] = SortData[N];
		}
		/* 偶数 */
		else
		{
			pDst[i] = (SortData[N] + SortData[N-1])/2;
		}
	}
}

/*
*********************************************************************************************************
*	函 数 名: MidFilterRT
*	功能说明: 中值滤波器,用于逐个数据实时滤波。
*	形    参: pSrc 源数据地址。
*             pDst 滤波后数据地址。
*             ucFlag 1表示首次滤波,后面继续滤波,需将其设置为0。
*             order 至少2阶。
*	返 回 值: 无
*********************************************************************************************************
*/
void MidFilterRT(float32_t *pSrc, float32_t *pDst, uint8_t ucFlag, uint32_t order)
{
	arm_sort_instance_f32 S;
	uint32_t N, i;
	
	static uint32_t CountFlag = 0;
	
	
	S.dir = ARM_SORT_ASCENDING;
	S.alg = ARM_SORT_QUICK;
	
	N = order / 2;
	
	/* 首次滤波先清零 */
	if(ucFlag == 1)
	{
		CountFlag = 0;
	}
	
	/* 填充数据 */
	if(CountFlag < order)
	{
		TempDate[CountFlag] = pSrc[0];
		CountFlag++;
	}
	else
	{
		for(i =0; i < order - 1; i++)
		{
			TempDate[i] = TempDate[1 + i];  
		}
		TempDate[order - 1] = pSrc[0];
	}
	
	/* 排序 */
	arm_sort_f32(&S, &TempDate[0], &SortData[0], order);
	
	/* 奇数 */
	if(N)
	{
		pDst[0] = SortData[N];
	}
	/* 偶数 */
	else
	{
		pDst[0] = (SortData[N] + SortData[N-1])/2;
	}
}

4.实现结果对比

图片1-1(血氧信号)

在这里插入图片描述

  • 5
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值