|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
如标题,手头暂时没有stc15的单片机,想来stc12有内置的ad,于是就用内置的做了一个ad转换,第一次测量一路ad,10位精度,基准用供电电压,然后数值乱跳,现在改用两路测量,8位精度,基准用看大网上说的是用431做基准,但是手头没有,本着节约(不想再买的,也就是动手d着玩)的原则,直接用1117-2.5v的稳压芯片代替,测试通过,数值没有第一次跳的厉害了,但是测量还是不准,万用表测单节干电池是1.52v 用做的测电压在1.2~1.6之间乱跳,又看了一下网上的教程,说是需要用软件滤波,然后又百度软件滤波,看的头晕了,也没看明白个什么,就此发帖想问题一下各位,有用软件滤波的没,就是那个中位值平均算法,取12个数据掐头去尾算平均,废话不说了,直接贴程序,写的比较乱。。。
下面是程序
#include<reg52.h>
#define u8 unsigned char
#define u16 unsigned int
sfr P1M1=0x91;
sfr P1ASF=0x9d;
sfr ADC_CONTR=0xbc;
sfr ADC_RES=0xbd;
sfr ADC_RESL=0Xbe;
sbit a=P0^0;
sbit b=P0^1;
sbit c=P0^2;
sbit d=P0^3;
sbit e=P0^4;
sbit f=P0^5;
sbit g=P0^6;
sbit h=P0^7;
sbit p20=P2^0;
sbit p21=P2^1;
sbit p22=P2^2;
sbit p23=P2^3;
unsigned char data1;
unsigned char data2;
unsigned char data3;
unsigned char data4;
void delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
/*void delay10us() //@12.000MHz
{
unsigned char i;
i = 27;
while (--i);
} */
void delayms(unsigned int n) //毫秒延时
{
while(n--)
{
delay1ms();
}
}
void display(unsigned char n) //数码管显示函数
{
if(n==1)
{a=1;b=0;c=0;d=1;e=1;f=1;g=1; //1
}
if(n==2){a=0;b=0;c=1;f=1;g=0;e=0;d=0; //2
}
if(n==3){a=0;b=0;c=0;d=0;e=1;f=1;g=0; //3
}
if(n==4){f=0;g=0;a=1;d=1;e=1;b=0;c=0; //4
}
if(n==5){a=0;b=1;e=1;f=0;g=0;c=0;d=0; //5
}
if(n==6){a=0;b=1;f=0;g=0;e=0;d=0;c=0; //6
}
if(n==7){a=0;b=0;c=0;d=1;e=1;f=1;g=1; //7
}
if(n==8){a=0;b=0;c=0;d=0;e=0;f=0;g=0; //8
}
if(n==9){a=0;b=0;c=0;d=0;e=1;f=0;g=0; //9
}
if(n==0){a=0;b=0;c=0;d=0;f=0;e=0;g=1; //0
}
}
void display_adc(unsigned int b) //b=1234 //计算函数
{
data1=b/1000; // 千位 1234/1000=1
data2=b%1000/100; // 百位 1234%1000/100=2
data3=b%100/10; // 十位 1234%100/10=3
data4=b%10; // 个位 1234%10=4
}
u8 adc_contr(u8 ch) //ad转换函数+通道选择
{
ADC_CONTR=0; //清空adc-contr
ADC_RES=0;
delayms(1); //延迟5ms
ADC_CONTR=ch|0x88; //10001111 打开adc转换电源,速度默认,打开adc转换,启用p17管脚ad转换
delayms(5); //延迟1ms保障数据可以写入
while(!(ADC_CONTR&0x10));
ADC_CONTR&=0x67; //关闭adc电源,关闭adc转换
delayms(1);
return ADC_RES;
// adc1=ADC_RES;//读出外部基准值
// ADC_RES=0;//清空adc——res的值
}
void main()
{
u16 adc,adc1,adc2,c,b/*,d*/;
P1M1=0xff; //设置io模式 p1口为高阻态
P1ASF=0xc0; //设置io工作模式 p17.p16为ad输入,p17为外部基准输入
P2=0;
P0=0xff;
while(1)
{
delayms(3);
c++;
if(c>100) //0.5秒转换一次
{
c=0;
adc1=adc_contr(7);//基准电压值
adc2=adc_contr(6);//测量电压值
adc=243*adc2/adc1; //基准是243,计算被测电压
// adc=adc*4;
/* adc=adc*2; 这些是10位精度时的程序,现在是8位精度,所以注释起来了
adc=adc*10/51;
adc<<=2;
d=ADC_RESL;
d&=0x03;
adc|=d; */
display_adc(adc); //显示被测电压
}
b++;
if(b>=4)
{
b=0;
}
if(b==0)
{
P2=0xfe;
display(data1);
}
if(b==1)
{
P2=0xfd;
display(data2);
}
if(b==2)
{
P2=0xfb;
display(data3);
}
if(b==3)
{
P2=0xf7;
display(data4);
}
}
}
|
| |