做了个表: (液晶屏和ADC0804 与51单片机的连接关系请参考sbit,电路连接采用ADC0804的典型接法,关于VREF/2可以选用TL431)
/*MCU = STC89C52RCCLOCK = 12MHzADC = ADC0804DISPLAYER = LCM1601*/ /************************************************************/ #include <STC89C5xRC.h>#define uchar unsigned char#define uint unsigned intsbit lcm_rs = P3^6; sbit lcm_e = P3^7; sbit adc_cs = P3^5;sbit adc_rd = P3^4; sbit adc_wr = P3^3; sbit adc_intr = P3^2; uint temp, d1, d2, d3, d4;//临时变量和电压值的四位uint result;//用于临时保存ADC的输出void ad_init();//初始化ADCvoid ad_start();//启动ADCuint ad_read();//读取ADC输出void delay(uint n);//延时"n"msvoid write_command(uchar cc);//向液晶屏写命令"cc"void write_data(uchar dd);//向液晶屏写数据"dd"void lcm_init();//初始化液晶屏void display(uchar q, uchar w, uchar e, uchar r);//显示结果 /************************************************************/void main(){write_command(0x01);//清屏lcm_init();//初始化液晶屏ad_init();//初始化ADCwhile(1){ad_start();//启动ADCwhile(adc_intr == 1);{ result = ad_read();//读取ADC输出result = result * 200;//输出刻度*最小分辨值的10000倍d1 = result / 10000;//电压值最高位result = result % 10000;//除以最高位权重取余数d2 = result /1000;//电压值的次高位result = result % 1000;//除以次高位权重取余数d3 = result /100;//电压值的次低位result = result % 100;//除以次低位权重取余数d4 = result / 10;//电压值的最低位;display(d1, d2, d3, d4);//显示结果 } } } /************************************************************/ void ad_init(){adc_cs = 1; adc_wr = 1; adc_rd = 1; }
void ad_start(){//P1 = 0xff; adc_cs = 0; adc_wr = 0; delay(5); adc_cs = 1; adc_wr = 1; delay(100); }
uint ad_read(){adc_cs = 0; adc_rd = 0; delay(5); temp = P1; adc_rd = 1; adc_cs = 1; adc_wr = 1; return (temp); }
void delay(uint n){uchar a,b,c; for(c = n; c>0; c--) for(b = 142; b>0; b--) for(a = 2; a>0; a--); }
void write_command(uchar cc){P0 = cc; lcm_rs = 0; lcm_e = 1; lcm_e = 0; delay(2); }
void write_data(uchar dd){P0 = dd; lcm_rs = 1; lcm_e = 1; lcm_e = 0; delay(5); }
void lcm_init(){lcm_e = 0; write_command(0x38);//设置8bit接口模式,2行5*7write_command(0x0c);//关闭光标,不闪烁write_command(0x06);//设置输入方式,增量不移位write_command(0x01);//清屏 }
void display(uchar q, uchar w, uchar e, uchar r){write_command(0x80 + 0x00);//选中第1个字符对应的RAM地址write_data(0x30 + q);//显示电压值的最高位write_command(0x80 + 0x01);//选中第2个字符对应的RAM地址write_data('.');//显示小数点write_command(0x80 + 0x02);//选中第3个字符对应的RAM地址write_data(0x30 + w);//显示电压值的次高位write_command(0x80 + 0x03);//选中第4个字符对应的RAM地址write_data(0x30 + e);//显示电压值的次低位write_command(0x80 + 0x04);//选中第5个字符对应的RAM地址write_data(0x30 + r);//显示电压值的最低位write_command(0x80 + 0x05);//选中第6个字符对应的RAM地址write_data('V');//显示单位"V" } /**********************************************************************/因为ADC只有8bit(0~255共256个刻度),所以当参考电压=2.55V且电源电压=5.1V时,最小分辨值=0.02V.
1V
2V
3V
4V
5V
2.5V
1.8V
2.46V(反正只要输入0.02的倍数,看起来就“一字不差”) ---------------------------------------------------------------
更多作品见:
AT89C2051 + BH1750FVI【照度计】 http://bbs.mydigit.cn/read.php?tid=2513384AT89S51 + DS18B20【温度计】 http://bbs.mydigit.cn/read.php?tid=2515015