软件滤波软件滤波是利用CPU强大的计算运算功能,通过某种数值运算,达到改变输入信号中所含频率分量的相对比例、或滤除某些频率分量的目的。实验中往往会因为噪声、干扰、温度、环境以及元器件或者设备等诸多因素的影响,造成采集到的数据达不到预期效果,例如采集到的“坏点”数据会对数据的分析以及结果造成不利的影响。这个时候可以采用软件滤波的方法对采集到的数据进行处理,减小抖动偏差,使采集到的数据尽可能的准确。此外除了可使用(有源、无源)滤波器对信号或波形进行平滑处理外,还可以先将波形用A/D采集,然后使用软件滤波,昀后通过D/A输出波形,同样可以起到对波形的平滑处理和消除毛刺等效果。软件滤波的方法有很多种,下面介绍常用的几种,不同的滤波方法应用的场合和环境也不用,应根据具体情况选择使用。为了直观体现出这几种滤波方法对不同噪声的滤波效果,我们人为生成了几段基本信号的组合,然后在它们的波形上叠加上不同的噪声,测试这些滤波方法在不同信号、不同噪声下的输出结果,实验数据如下图所示:在这段长度为800点,昀大值为65535的测试样本中,组合了以下几种情况:1.起始阶段是一段表达式近似为x的数据,用来模拟大多数系统从0开始启动的采样波形,该段信号受到了约为信号本身51强度的随机噪声的干扰,用以测试滤波函数对噪声的过滤程度。2.第二段是一段长度为200点的方波信号,其上叠加了幅度为信号本身101的毛刺噪声,测试函数对直流采样过程中毛刺的过滤效果以及对阶跃信号的响应速度。3.第三段为一段均匀上升的斜坡信号,但是叠加了几个三角形的噪声信号,用来模拟一些高惯性系统受到脉冲冲击后产生的周期较长的干扰杂波。4.第四段是一段混有信号本身101强度的随机噪声与41强度的毛刺噪声,模拟了平时在正弦逆变类题目中常常碰到的系统底噪与周期性开关噪声。5.昀后一段是直流信号上叠加了一个长周期的小幅正弦纹波,同时伴有一定的毛刺,用来模拟DC-DC类题目中常出现的输出伴纹波信号。上面列出的组合大致涵盖了电子设计竞赛中电源类常见的几种情况,由于涉及到PID闭环调节,因此精确的采样与滤波对实现高精度的输出控制与快速反馈至关重要。下面我们就分别介绍这些算法的实现过程与应用效果。限幅滤波限幅滤波又称为程序判断滤波,根据多次采集到的数据,如果当前采集值与前一次采集的数值相差一般维持在一定的偏差D内,则将每次采集到的数据和前一次的数据进行比较,如果他们的差的绝对值小于D则本次采集到的数据有效,否则无效舍弃。示例代码#includestdlib.h/*********************限幅滤波***********************/*sampleValue:当前采样值/*return滤波输出值/***************************************************/#defineAMPLIMIT8192intlastValue=-1;unsignedintAmpLimitFilter(unsignedintsampleValue){if(-1==lastValue)lastValue=sampleValue;//限幅判断if(abs(sampleValue-lastValue)AMPLIMIT){returnlastValue;}else{lastValue=sampleValue;returnsampleValue;}}滤波效果适用分析限幅滤波程序设计简单、运算速度快、占用RAM少,是一种昀简单的基本滤波方法。能够克服偶然因素引入的脉冲干扰,也可以消除波形上的尖峰毛刺,但是不能抑制周期性的干扰,而且其完全削除大幅度的阶跃信号,容易造成控制失调,一般不适用于开关电源这类变化剧烈,需要迅速反馈的场景,适用于水温控制等变化缓慢,安全性高的应用。中值滤波将原来的采样间隔T进行细分,也就是在原来的采样间隔T内采样N次,然后把N次采样值按照大小排序,取中间值为本次采样值。示例代码/*********************中值滤波***********************/**sampleGet():采样函数指针,返回unsignedint类型/*return滤波输出值/***************************************************/#defineMID_NUM5unsignedintMidFilter(unsignedint*sampleGet()){unsignedchari;unsignedintvalue_buf[MID_NUM]={0};for(i=0;iMID_NUM;i++){value_buf[i]=sampleGet();}unsignedintmid;//冒泡排序for(i=0;iMID_NUM;i++){intj;for(j=i+1;jMID_NUM;j++){if(value_buf[i]value_buf[j]){mid=value_buf[i];value_buf[i]=value_buf[j];value_buf[j]=mid;}}}mid=value_buf[MID_NUM/2];returnmid;}滤波效果适用分析这种滤波方法能够有效的克服偶然因素引起的波动干扰,特别是对于像温度、液位等变化缓慢的被测参数有良好的滤波效果,但是对于流量、速度或者其他快速变化的信号参数则不适合使用这种方法。中值滤波法的程序设计要稍复杂一些,排序可以使用冒泡法或者选择排序法等,由于引入了排序算法,所以该方法不能处理速度要求很高的信号。其运算处理速度和占用的RAM直接受所选择的数值N决定。算术平均滤波该方法也是先将原来设计要求的采样间隔T进行细分,在T内采样N次,但是对于采集进来的数据不是进行排序,而是进行算术平均,算术平均的结果作为本次采样值。N值的选取比较关键,N值较大者处理信号的平滑度会较高,但是灵敏度降低;相反,N值较小者处理信号的灵敏度提高,但是平滑度降低。示例代码/*********************均值滤波***********************/**sampleGet():采样函数指针,返回unsignedint类型/*return滤波输出值/***************************************************/#defineAVG_NUM5unsignedintAvgFilter(unsignedint*sampleGet()){unsignedchari;unsignedlongintsum=0;for(i=0;iAVG_NUM;i++){sum+=(unsignedint)sampleGet();}return(sum/AVG_NUM);}滤波效果适用分析这种滤波方法是适用于对具有随机干扰的信号进行处理,并且被处理的信号必须具有一个平均值,信号在这个平均值上下波动。该方法对于高速信号并不适用。对于毛刺信号,可以看到均值滤波将其分担到了周围的采样点上,不如中值滤波那样能够完全去除。但是对于随机噪声信号,由于其理论均值为0,均值滤波对第一段噪声有良好的滤除效果。该滤波方法运算处理速度和RAM的占用率也受所选择的数值N决定,可以使用时间复杂度较低的排序方法降低运算开销。递推平均滤波递推平均滤波又称为滑动平均滤波,是将连续N个采样值设为一个先入先出的队列,队列的长度为N,每次采样得到的新数据加入队尾,并扔掉原队列的队首,然后对队列中的N个数据进行算术平均,获得的结果作为此次采样值。示例代码/*******************递推均值滤波*********************/*sampleQueue[SLIDE_AVG_NUM]:采样队列/*sampleValue:当前采样值/*return滤波输出值/***************************************************/#defineSLIDE_AVG_NUM5unsignedintsampleQueue[SLIDE_AVG_NUM]={0};unsignedintSlideAvgFilter(unsignedintsampleValue){unsignedinti;unsignedlongintsum=0;for(i=0;iSLIDE_AVG_NUM-1;i++)//刷新队列{sampleQueue[i]=sampleQueue[i+1];}sampleQueue[i]=sampleValue;for(i=0;iSLIDE_AVG_NUM;i++)//求和{sum+=sampleQueue[i];}return(sum/SLIDE_AVG_NUM);//取平均}滤波效果适用分析上图为滤波长度为5的输出波形,下图为滤波长度为20的输出波形。可以看到长度为20的波形更好但延迟也更大。可见该方法对于周期性干扰有良好的抑制作用,平滑度也很高。但是灵敏度较低,对于偶然出现的脉冲干扰的抑制作用较差,不适用于脉冲干扰比较严重的场合,其运算处理速度和RAM的占用率也直接受N值影响。另外,这种方法还有一个特殊用法:制作成软件陷波器,滤除某个单一频率信号的干扰(如工频干扰)。具体实现方法介绍如下:由于正弦波一个周期内任取N个等分点的幅值和为零,其它周期波形的N等分点的幅值和为常数C,设每次采样值为iX,采样的平均值为101NiiXNY。若取fSN(其中S为每秒的采样次数即采样率;f是要消除的波形的频率,S和N都取整数),这样昀终的结果就是Y-C,对于50Hz的工频干扰,C为零,只要选择合适的N和S就可以直接将其消除,构成一个陷波器。对于本测试样例,我们针对昀后一段的纹波设计滤波器,由于这里是测试的一组数组,没有采样率概念,但是根据前面的关系换算,设置滤波点数为100点,对昀后一段纹波进行了较好的滤除,由于这一段数据较少,加之前面数据的相移影响,读者可自己构造一段足够长的纹波信号验证,效果将更加明显。中值平均滤波中值平均滤波也称为防脉冲干扰平均滤波,相当于中值滤波和算术平均滤波思想的结合。连续采样N个数据,去掉其中的昀大值和昀小值,求剩下的N-2个数据的算术平均作为一次采样值。示例代码/*******************中值平均滤波*********************/**sampleGet():采样函数指针,返回unsignedint类型/*return滤波输出值/***************************************************/#defineMID_AVG_NUM5unsignedintMidAvgFilter(unsignedint*sampleGet()){unsignedchari;unsignedintvalue_buf[MID_AVG_NUM]={0};unsignedintmax,min;unsignedlongintsum=0;for(i=0;iMID_AVG_NUM;i++){value_buf[i]=sampleGet();}max=0;min=0xffffffff;for(i=0;iMID_AVG_NUM;i++){sum+=value_buf[i];//求和if(value_buf[i]max){max=value_buf[i];//找出昀大值}if(value_buf[i]min){min=value_buf[i];//找出昀小值}}return(sum-min-max)/(MID_AVG_NUM-2);//去掉昀大昀小值,取平均}滤波效果适用分析此法综合了两种滤波法的优点,可以有效抑制、消除脉冲干扰,同时相对于纯中值滤波更加平滑,但由于计算开销加上均值的延迟作用,它也只能用在速度比较慢的场合,不适合高速环境,运算处理速度和RAM占有率由N决定。递推中值平均滤波递推中值平均滤波也称为滑动中值平均滤波,与上一种不同的是采用滑动方法对序列采样,不降低系统采样