论坛元老
 
- 积分
- 3347
- 金钱
- 3347
- 注册时间
- 2013-4-10
- 在线时间
- 333 小时
|
发表于 2015-6-9 04:54:22
|
显示全部楼层
在网上买一本【感悟设计】这本书,来看一下,上面有关于10种软件滤波的算法详解,我也是从上面学到的,以下是我用于工程中的一段代码,希望对你有用
/********************************************************************************************
函数名:GlideValueFilter() 8次递推(滑动)平均滤波法+一阶滞后滤波法
调 用:GlideValueFilter()
参 数:当前ADC转换的结果值
返回值:滤波后的ADC采样值
说 明: ADC_POWRE[]当前函数用来保存数据的数组,属于全局变量
OLD_DATA 前一次采样的结果(全局变量)
一阶滞后滤波系数取64
result 本次采样的新数据
/*******************************************************************************************/
void GlideValueFilter(unsigned char ch)
{
unsigned int Sum,NEW_DATA;
unsigned char FX,i,ChaZhi;
ADC_CONTR = ADC_POWER | ADC_SPEEDH | ch | ADC_START;
_nop_(); //等待4个NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG; //Close ADC
ADC_Dat[8] = ADC_RES; //采样数据,放到数组的最高位
Sum = 0;
for(i = 0; i < 8; i++)
{
ADC_Dat=ADC_Dat[i+1];//所有数据左移,低位去掉
Sum += ADC_Dat; //求和
}
NEW_DATA = Sum/8; //求平均值
if(NEW_DATA < OLD_DATA) //如果新采样值小于前次采样值
{
FX = 0; //记录数据变化方向
ChaZhi = OLD_DATA - NEW_DATA;
OLD_DATA -= (ChaZhi*XiShu +128)/256; //+128是为了四舍五入
}
else{
if(NEW_DATA > OLD_DATA) //如果新采样值大于前次采样值
{
FX = 1; //记录数据变化方向
ChaZhi = NEW_DATA - OLD_DATA;
OLD_DATA += (ChaZhi*XiShu +128)/256; //+128是为了四舍五入
}
}
//动态调节滤波系数
if(FX != FangXiang){JiShuQi = 0; XiShu = 0;}//两次变化的方向不同,清零计数器及滤波系数
else{
if(ChaZhi > ZUIDACHAZHI)JiShuQi += 3; //差值1大于阈值,计数器加3
else JiShuQi++; //计数器加1
if(JiShuQi >JISHUZUIDAZHI) //计数器已达最大值
{
XiShu += ZENGLIANG; //调整一阶滤波系数
if(XiShu > 255)XiShu = 255; //如果已达最大值,则取最大值
JiShuQi = 0; //消抖计数器清零
}
}
FangXiang = FX; //保存当前次的变化方向
}
滤波后的值在【OLD_DATA】中
程序中还需三个全局变量
unsigned char data FangXiang = 0; //方向(静态变量)
unsigned char data JiShuQi = 0; //计数器(静态变量)
unsigned char data XiShu = 128; //滤波系数(静态变量)
#define ZENGLIANG 15u //动态一阶滤波系数增量值
#define JISHUZUIDAZHI 10u //动态一阶滤波消抖动计数器最大值
#define ZUIDACHAZHI 10u //两次结果的差值 |
|