上一篇通过在Matlab仿真验证了一阶低通滤波的定点实现算法,本篇通过定点C语言在DSP上成功验证该算法,包括滤波时间c的理论对应,以及滤波精度(控制在±1个当量)。
1、定点C语言实现一阶低通滤波,在DSP成功验证滤波时间和稳态精度,C语言如下:
头文件定义IQ的缩放倍数(2^ IQLEN ),如下:
#define IQLEN 15
#define IQ_REMAIDER(x) (x&0x7FFF) /*IQLEN=15 32768的求余*/
#define IQ_Ts _IQ(0.1) /*采样时间/ms*/
初始化函数初始化滤波系数:
sDatIq.iqViFilCoe = (IQ_Ts << IQLEN)/sFltTconst.i32Vi; /*采样时间/滤波时间常数:>>15比值放大*/
sDatIq.iqVoFilCoe = (IQ_Ts << IQLEN)/sFltTconst.i32Vo;
sDatIq.iqViFilCoeOld = _IQ(1.0) - sDatIq.iqViFilCoe; /*当前权重系数与历史权重系数互补*/
sDatIq.iqVoFilCoeOld = _IQ(1.0) - sDatIq.iqVoFilCoe;
……
100us周期任务执行如下代码:
//定点低通滤波
sDatIq.iqViFilResult = sDatIq.iqViFilCoe * /* SysPara.i16VI_Ad*/4090 + SysPara.i16VIFil_Ad * sDatIq.iqViFilCoeOld;
sDatIq.iqViRemainSum += IQ_REMAIDER(sDatIq.iqViFilResult); /*当不足一个当量,定点右移舍弃了余数,需对余数累计,当累加到个当量时送入输出*/
SysPara.i16VIFil_Ad = (sDatIq.iqViFilResult >>IQLEN) + (sDatIq.iqViRemainSum >> IQLEN);
sDatIq.iqViRemainSum -= ((sDatIq.iqViRemainSum >> IQLEN) << IQLEN); /*送出去的当量从余数累加器中扣除*/
2、响应曲线。看变量SysPara.i16VIFil_Ad的输出曲线和终值----
参数:采样时间100us,滤波时间常数5ms(1c=5ms,1c对应从0缓升至63.2%稳态值的时间)。终值给定4090,通过下图中的缓慢上升曲线,5ms时滤波后的实际值2615,非常接近4090*0.632= 2584。
3、滤波输出稳定精度,稳定值也就是4090±1(如下图采样数组,存SysPara.i16VIFil_Adm每拍数据,直到存满)。即±1个当量。验证了该算法。从图中不难发现,一阶低通滤波的达到稳态是大约4-5个滤波时间常数。