//**************************************************************
/*简易数字电压表制作——ADC0832模数转换应用程序(C语言版)
/*目标器件:AT89S52 */
/*晶振:12.000MHZ */
/*编译环境:Keil uVision2 V2.12 */
//*****************************************************************
#include #include #define uint unsigned int #define uchar unsigned char /*******************************定义全局变量********************************/ unsigned char dat=0x00 ; //AD值 unsigned char count = 0x00; //定时器计数 unsigned char channel; //通道变量 //ADC0832的引脚 sbit ADCS =P1^4; //ADC0832 chip seclect sbit ADDI =P1^6; //ADC0832 k in sbit ADDO =P1^6; //ADC0832 k out sbit ADCLK =P1^5; //ADC0832 clock signal unsigned char dispbitcode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位扫描 unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff}; //共阳数码管字段码 unsigned char dispbuf[3]; /*******************************共阳LED段码表*******************************/ unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uint temp; uchar dat; //获取ADC转换回来的值 /**************************************************************************** 函数功能:AD转换子程序 入口参数:CH 出口参数:dat ****************************************************************************/ //采集并返回 unsigned int Adc0832(unsigned char channel) //AD转换,返回结果 { uchar i=0; uchar j; uint dat=0; uchar ndat=0; if(channel==0)channel=2; if(channel==1)channel=3; ADDI=1; _nop_(); _nop_(); ADCS=0;//拉低CS端 _nop_(); _nop_(); ADCLK=1;//拉高CLK端 _nop_(); _nop_(); ADCLK=0;//拉低CLK端,形成下降沿1 _nop_(); _nop_(); ADCLK=1;//拉高CLK端 ADDI=channel&0x1; _nop_(); _nop_(); ADCLK=0;//拉低CLK端,形成下降沿2 _nop_(); _nop_(); ADCLK=1;//拉高CLK端 ADDI=(channel>>1)&0x1; _nop_(); _nop_(); ADCLK=0;//拉低CLK端,形成下降沿3 ADDI=1;//控制命令结束 _nop_(); _nop_(); dat=0; for(i=0;i<8;i++) { dat|=ADDO;//收数据 ADCLK=1; _nop_(); _nop_(); ADCLK=0;//形成一次时钟脉冲 _nop_(); _nop_(); dat<<=1; if(i==7)dat|=ADDO; } for(i=0;i<8;i++) { j=0; j=j|ADDO;//收数据 ADCLK=1; _nop_(); _nop_(); ADCLK=0;//形成一次时钟脉冲 _nop_(); _nop_(); j=j<<7; ndat=ndat|j; if(i<7)ndat>>=1; } ADCS=1;//拉低CS端 ADCLK=0;//拉低CLK端 ADDO=1;//拉高数据端,回到初始状态 dat<<=8; dat|=ndat; return(dat); //return ad k } /************************************************************************** 函数功能:延时子程序 入口参数: 出口参数: ****************************************************************************/ void delay(void) { int k; for(k=0;k<500;k++); } /****************************************************************************** 函数功能:数码管显示函数 入口参数: 出口参数: ******************************************************************************/ void display(void) { P2=0xff; P0=tab[dispbuf[2]] & 0x7f; //显示个位和小数点 P2=0xfb; delay(); P2=0xff; P0=tab[dispbuf[1]]; //显示小数点后第一位 P2=0xfd; delay(); P2=0xff; P0=tab[dispbuf[0]]; //显示小数点后第二位 P2=0xfe; delay(); } /**************************************************************************** 函数功能:定时器中断延时程序 这一段的作用时隔一段时间抽样一次 否侧显示的最后一位会不稳定 入口参数: 出口参数: ****************************************************************************/ void timer0(void) interrupt 1 { TMOD = 0x01; TH0 = 0x00; TL0 = 0x00; IE = 0x82; TR0 = 01; count++; if (count == 0x0A) { count = 0x00; dat= Adc0832(channel); } } /**************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************/ void main(void) { P2=0xff; //端口初始化 P0=0xff; channel=0x00; //channel=0 TMOD = 0x01; TH0 = 0x00; TL0 = 0x00; IE = 0x82; TR0 = 01; while(1) { temp=dat*1.0/255*500; //电压值转换,5V做为参考电压,分成256份。 dispbuf[0]=temp%10; //个位 dispbuf[1]=temp/10%10; //十位 dispbuf[2]=temp/100%10; //百位 display(); } }
相关文章