参考文献
[1]姜志海,黄玉清等著.单片机原理及应用[M] .北京:电子工业出版社.2005年7月
[2]魏立峰.单片机原理及应用技术.北京大学出版社,2005年
[3]于殿泓、王新年.单片机原理与程序设计实验教程.西安电子科技大学出版社,2007年5月
[4]谢维成、杨加国.单片机原理与应用及C51程序设计实例.电子工业出版社,2006年3月
[5]苗红霞.单片机实现数字电压表的软硬件设计[J] .河海大学常州分校学报,2002,(03).
[6]宋凤娟,孙军,李国忠.基于89C51单片机的数字电压表设计[J] .工业控制计算机,2007,(04).
[7]胡健.单片机原理及接口技术.北京:机械工业出版社,2004年10月 [8]王毓银.数字电路逻辑设计.高等教育出版社,2005年12月
18
附录
完整代码如下:
/*************************导入头文件*****************************/ #include
unsigned char dat[] = {0x00,0x00}; unsigned char datt[]={0x00,0x00}; unsigned char data1= 0x00; unsigned char data2= 0x00; unsigned char dat2= 0x00; unsigned char count = 0x00; unsigned char CH;
unsigned char dis[] = {0x00, 0x00}; unsigned char m; unsigned char i,j;
/***************************共阳LED段码表*************************/ unsigned char code
tab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
/*****************************延时子程序**************************/ void delay(unsigned char m) {
int k;
for(k=10;k /******************************读取电压值*************************/ unsigned char adc0832(unsigned char CH) 19 { unsigned char i,test,adval; adval = 0x00; test = 0x00; Clk = 0; //初始化 //第1个时钟脉冲下沉之前DI端必须是高电平,表示启始信号 DATI = 1; _nop_(); //运行一个机器周期 CS = 0; _nop_(); Clk = 1; _nop_(); if ( CH == 0x00 )//选择了通道0 { Clk = 0; DATI = 1; //通道0的第一位,第2个时钟脉冲下沉之前DI端是高电平 _nop_(); Clk = 1; _nop_(); Clk = 0; DATI = 0; //通道0的第二位,第3个时钟脉冲的下沉之前DI端是低电平 } else { Clk = 0; //选择了通道1 _nop_(); Clk = 1; _nop_(); DATI = 1; //通道1的第一位,第2个时钟脉冲下沉之前DI端是高电平 _nop_(); Clk = 1; 20 _nop_(); Clk = 0; DATI = 1; //通道1的第二位,第3个时钟脉冲下沉之前DI端是高电平 _nop_(); Clk = 1; _nop_(); } Clk = 0; DATI = 1; for( i = 0;i < 8;i++ ) //读取前8位的值 { _nop_(); adval <<= 1; Clk = 1; _nop_(); Clk = 0; if (DATO) adval |= 0x01; else adval |= 0x00; } for (i = 0; i < 8; i++) //读取后8位的值 { test >>= 1; if (DATO) test |= 0x80; else test |= 0x00; _nop_(); Clk = 1; _nop_(); 21 Clk = 0; } if (adval == test) //比较前8位与后8位的值,如果不相同去 dat[CH] = test; } /*********************将电压值转换成小数形式*********************/ void convdata(unsigned char i) { dis[0] = i/51; //个位 dis[1] = (unsigned char)(((float)i/51-i/51)*10);//小数点后第一位 } /*************************数码管显示子程序************************/ void display(void) { if(CH==0) { P2=0x1f; //选中第一个LED灯 _nop_(); CS = 1; //释放ADC0832 DATO = 1; Clk = 1; return dat[CH]; P0=tab[dis[0]] & 0xfe; //将通道0的个位在第一个LED灯上显示 delay(70); P2=0x2f; //选中第二个LED灯 P0=tab[dis[1]]; //将通道0的小数点后一位在第二个LED灯上显示 delay(20); } else { P2=0x4f; //选中第三个LED灯 22 P0=tab[dis[0]] & 0xfe; //将通道1的个位在第三个LED灯上显示 delay(70); P2=0x8f; //选中第四个LED灯 //将通道1的小数点后一位在第四个LED灯上显示 P0=tab[dis[1]]; delay(20); } } /****************************主程序**************************/ void main(void) { P2=0x0f; //端口初始化 P0=0xff; delay(20); while(1) //主循环 { for(CH=0;CH<=1;CH++) //选择0通道 { datt[CH]=adc0832(CH); convdata(datt[CH]); //数据转换 display(); //显示数值 } } } 23