刚学单片机,学到AD转换,但转换后数据非常不稳定,上网查滤波法,方法很多:限幅滤波法,中位值滤波法,算术平均滤波法,
递推平均滤波法,中位值平均滤波法,限幅平均滤波法,一阶滞后滤波法,加权
递推平均滤波法,消抖滤波法,限幅消抖滤波法,IIR
数字滤波器等等...但全部太深奥,根本看不懂。
无奈只有自己找办法,不停实验,终于找到最简单的办法,效果也很好。现在把程序放上来,希望大神门指点指点,有哪里做得不好需要改进的地方。
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9共阳数码管显示
uchar tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //0-9带点显示
sbit st=P2^0;
sbit eoc=P2^1;
sbit oe=P2^2;
sbit clk=P2^3;
sbit b1=P3^5;
sbit b2=P3^6;
sbit b3=P3^7;
uchar ad_data; //储存8位ADC0809CCN采集的数据
void delay(void)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void delaynms(uchar n)
{
uchar i,j;
for(i=0;i<n;i++)
for(j=0;j<250;j++)
;
}
void init(void)
{
TMOD=0x02;
TH0=236; //为AD提供时钟信号
TL0=236;
EA=1;
ET0=1;
TR0=1;
st=0;
oe=0;
}
void display(uint x)
{
x/=0.51;
P1=0xff;
P1=tab1[x/100];
b3=0;
delaynms(2);
b3=1;
P1=0xff;
P1=tab[x/10%10];
b2=0;
delaynms(2);
b2=1;
P1=0xff;
P1=tab[x%10];
b1=0;
delaynms(2);
b1=1;
}
void ad(void)
{
st=0;
delay();
st=1;
delay();
st=0;
delay();
while(eoc==0);
oe=1;
ad_data=P0;
oe=0;
}
void main()
{
uchar y,k,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9;
init();
while(1)
{
ad();
y=ad_data%10; //取采集数据末位
switch(y)
{
case 0: c0++;
if(c0>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break; //先8完全把干扰排除了 数据完全是AD测到的不加修饰的数据 下同
case 1: c1++;
if(c1>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 2: c2++;
if(c2>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 3: c3++;
if(c3>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 4: c4++;
if(c4>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 5: c5++;
if(c5>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 6: c6++;
if(c6>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 7: c7++;
if(c7>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 8: c8++;
if(c8>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
case 9: c9++;
if(c9>7) {k=ad_data;c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;c6=0;c7=0;c8=0;c9=0;}
break;
}
display(k);
}
}
void T0time() interrupt 1 using 1
{
clk=~clk;
}
[ 此帖被you666在2014-06-30 21:50重新编辑 ]