基于单片机的数字电压表制作——ADC0832模数转换应用程序(C语言) 主要部件:AT89S51 ADC0832 八段数码管 关键字:ADC0832程序C语言数字电压表
本文所描述的数字电压表是利用ADC0832模数转换芯片完成的。该芯片能将0~5V的模拟电压量转换为0~255级的数字量,所以本文描述的数字电压表的量程为0~5V。
说实在话,量程只有5V的电压表没有什么实际的意义,而且也没有人无聊到自己会去做一个没有意义的电压表。但是通过这个简易电压表的制作你可以对模数转换芯片有一定的了解,对以后做真正有用的电路打下基础。而且,对于那些做毕业设计的同学也是一种参考。这也就是本文的意义所在。 ADC0832的资料百度一下可以找到一大堆,我就不在这里赘述了。这里只给出连接图。
以下是程序部分:
该程序是本人自编的,经测试可用,但不保证程序的可靠性及稳定性。若有转载请标明出处。
如果有同学将本程序烧写到单片机里却不能正常工作的,请注意以下三点:
1、 是否将端口重新定义。每个单片机开发板的引脚连接都是不一样的,若不加修改直接把程序烧写到单片机里,那是绝对不能正常工作的。
2、 是否正确选择通道值。ADC0832有两个模拟输入端口(也就是我说的通道),你要先弄清楚你用的
是那个通道,并在main函数中设置相应的通道值(以CH命名的那个变量)。本程序默认使用0通道,如果0通道不行就改成1通道,反正不是0通道就是1通道。
3、 如果你做的电压表在保证电路连接正确且没有以上两点问题的情况下,还是不能正常工作,请将程序中的“if (adval == test)”这一行删掉。其实这一点我个人也不清楚到底有没有问题。我有两个单片机开发板,其中一个必须要把那一行删掉才能工作。这说明ADC0832读出的前8位与后8位数值不一样(确切的说应该是后8位反转的数值),这有悖于ADC0832的原理。我不知道到底是硬件还是软件出了问题,特此把这种现象标明。若有哪位同学知道其原因的还请多多指教。
/***********************************************************************************/ /*简易数字电压表制作——ADC0832模数转换应用程序(C语言版)*/
/*目标器件:AT89S51 */
/*晶
振:12.000MHZ */ /*编译环境:Keil uVision2 V2.12 */ /***********************************************************************************/ /*********************************包含头文件********************************/ #include
/*********************************端口定义**********************************/ sbit CS = P3^5; sbit Clk = P3^4; sbit DATI = P3^3; sbit DATO = P3^3;
/*******************************定义全局变量********************************/ unsigned char dat = 0x00; //AD值 unsigned char count = 0x00; //定时器计数 unsigned char CH; //通道变量
unsigned char dis[] = {0x00, 0x00, 0x00}; //显示数值
/*******************************共阳LED段码表*******************************/ unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; /**************************************************************************** 函数功能:AD转换子程序 入口参数:CH 出口参数:dat
****************************************************************************/ unsigned char adc0832(unsigned char CH) {
unsigned char i,test,adval; adval = 0x00; test = 0x00;
Clk = 0; //初始化 DATI = 1; _nop_(); CS = 0; _nop_(); Clk = 1; _nop_();
if ( CH == 0x00 ) //通道选择 {
Clk = 0;
DATI = 1; //通道0的第一位 _nop_(); Clk = 1; _nop_();
Clk = 0;
DATI = 0; //通道0的第二位 _nop_();
Clk = 1; _nop_(); } else {
Clk = 0;
DATI = 1; //通道1的第一位 _nop_(); Clk = 1; _nop_();
Clk = 0;
DATI = 1; //通道1的第二位 _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_(); Clk = 0; }
if (adval == test) //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉
dat = test;
_nop_();
CS = 1; //释放ADC0832 DATO = 1; Clk = 1; return dat; }
/**************************************************************************** 函数功能:延时子程序 入口参数: 出口参数:
****************************************************************************/ void delay(void) {
int k;
for(k=0;k<500;k++); }
/**************************************************************************** 函数功能:将0-255级换算成0.00-5.00的电压数值 入口参数:i 出口参数: