基于单片机的0-24V电压表 电路原理图如下:
单片机源程序如下:
- #include"reg52.h"
- #include"intrins.h"
- typedef unsigned char uchar;
- typedef unsigned int uint;
- #define _Nop() _nop_()
- unsigned char data_char_table[]= {"0123456789ABCDEF"}; //LCD数据
- unsigned char Lcd_Dis1_table[] = {"Position:No. "}; //第一行显示框架
- unsigned char pos_char_table[] = {" D "}; // 显示位置
- unsigned char Lcd_Dis2_table[] = {"Voltage : V"}; //第二行显示框架
- unsigned char num_char_table[] = {" 9A.CD V"}; // 显示位置
- sbit lcd_rs_port=P2^5; //定义 LCD控制端口,根据硬件调整
- sbit lcd_rw_port=P2^6;
- sbit lcd_en_port=P2^7;
- sbit X=P3^4;
- sbit Y=P3^3;
- sbit Z=P3^2;
- #define lcd_data_port P0
- void lcd_delay(uchar ms); //LCD1602延时
- void lcd_busy_wait(); //LCD1602忙等待
- void lcd_command_write(uint command); //LCD1602命令字写入
- void lcd_system_reset(); //LCD1602初始化
- void lcd_char_write(uint x_pos,y_pos,lcd_dat); //LCD1602字符写入
- void lcd_bad_check(); //LCD1602坏点检查
- void Num_to_Disp(uchar i,uint Num); //显示数据处理
- void LcdDisp(uchar j,uint num); //液晶显示函数
- float adadverage();
- /*****定义与 ADC相关的特殊功能寄存器 *****/
- sfr ADC_CONTR= 0xBC; //ADC控制寄存器
- sfr ADC_RES = 0xBD; //ADChight8-bitresultregister
- sfr ADC_RESL = 0xBE; //ADClow2-bitresultregister
- sfr P1ASF = 0x9D; //P1口功能控制寄存器 P1ASF
- /************定义相应操作位***************/
- #define ADC_POWER 0x80 //ADC电源控制位,0:关闭,1:打开
- #define ADC_FLAG 0x10 //ADC结束标志位
- #define ADC_START 0x08 //ADC启动控制位
- #define ADC_SPEEDLL 0x00 //540clocks__________选择转换速度
- void InitADC(); //ADC初始化
- uint GetADCResult(uchar ch);
- void Delay(uint n); //延时程序
- void delay_1ms(uchar x);
- void decide();
- /*--------------------------------主函数 --------------------------------*/
- void main()
- {
- lcd_system_reset(); //LCD1602初始化
- lcd_bad_check(); //LCD1602坏点检查
- InitADC(); //初始化 ADC特殊功能寄存器
- while(1)
- {
- decide();
- Delay(1000);
- }
- }
- /*--------------------------------域值判断 ------------------------------*/
- void decide()
- {
- unsigned int res;
- float NUM;
- NUM=0.0;
- X=1;
- Y=1;
- Z=1;
- res=GetADCResult(0);
- NUM=(res*5.00/1024.0);
- NUM=NUM*5;
- if(NUM<4.99)
- {
- X=1;
- Y=1;
- Z=0;
- Delay(10);
- LcdDisp(4,adadverage());
- }
- else if(NUM>=4.99&&NUM<6.24)
- {
- X=0;
- Y=0;
- Z=1;
- Delay(10);
- LcdDisp(3,adadverage());
- }
- else if(NUM>=6.24&&NUM<8.2)
- {
- X=1;
- Y=0;
- Z=1;
- Delay(10);
- LcdDisp(2,adadverage());
- }
- else if(NUM>=8.2&&NUM<12.4)
- {
- X=0;
- Y=1;
- Z=1;
- Delay(10);
- LcdDisp(1,GetADCResult(0));
- }
- else if(NUM>=12.4&&NUM<25.0)
- {
- X=1;
- Y=1;
- Z=1;
- Delay(10);
- LcdDisp(0,adadverage());
- }
- else
- {
- LcdDisp(8,0);
- }
- }
- /*--------------------------------ADC取值 ------------------------------*/
- uint GetADCResult(uchar ch)
- {
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
- _nop_(); //Mustwaitbeforeinquiry
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR & ADC_FLAG)); //Waitcompleteflag
- ADC_CONTR &=ADC_FLAG; //Close ADC
- return(ADC_RES*4+ADC_RESL); //ReturnADCresult
- }
- /*AD初始化*/
- void InitADC()
- {
- P1ASF=P1|0x3f; //Set P1.0-P1.5 as an alogin putport
- ADC_RES =0; //Clearpreviousresult
- ADC_RESL=0;
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
- Delay(20);
- } //ADCpower-ondelayandStartA/Dconversion}
- ///////////////以下为 LCD显示数据处理/////////////////
- void Num_to_Disp(uchar i,uint Num)
- {
- float NUM;
- int xx,yy,zz,vv;
- NUM=(Num*5.00/1024.0);//计算公式:10-bitA/DConversionResult=1024x(Vin/Vcc)
- switch(i)
- {
- case 0:NUM=NUM*5.10;break;
- case 1:NUM=NUM*2.52;break;
- case 2:NUM=NUM*1.69;break;
- case 3:NUM=NUM*1.27;break;
- case 4:NUM=NUM*1.00;break;
- }
- xx=(int)NUM;
- yy=(int)((NUM-(float)(xx))*10);
- zz=(int)((NUM-(float)(xx))*100)%10;
- vv=(int)((NUM-(float)(xx))*1000)%10;
- num_char_table[9]=data_char_table[xx / 10]; //电压值十位
- num_char_table[10]=data_char_table[xx % 10]; //电压值个位
- num_char_table[12]=data_char_table[yy]; //电压值小数点后一位
- num_char_table[13]=data_char_table[zz]; //电压值小数点后两位
- num_char_table[14]=data_char_table[vv]; //电压值小数点后三位
- pos_char_table[13]=data_char_table[i]; //当前 ADC接口
- }
- //////////////////以下为 LCD显示////////////////////
- void LcdDisp(uchar j,uint num)
- {
- uint i=0;
- for(i=0;i<16;i++)
- {
- lcd_char_write(i,0,Lcd_Dis1_table[i]);
- lcd_char_write(i,1,Lcd_Dis2_table[i]); //显示框架
- }
- Num_to_Disp(j,num);
- lcd_char_write(13,0,pos_char_table[13]);
- for(i=9;i<15;i++)
- {
- lcd_char_write(i,1,num_char_table[i]); //显示电压
- }
- delay_1ms(100);
- }
- //////////////以下是 LCD1602驱动程序////////////////
- /*LCD1602延时*/
- void lcd_delay(uchar ms)
- {
- uchar j;
- while(ms--)
- {
- for(j=0;j<250;j++)
- {;}
- }
- }
- /*LCD1602忙等待*/
- void lcd_busy_wait()
- {
- lcd_rs_port=0;
- lcd_rw_port=1;
- lcd_en_port=1;
- lcd_data_port=0xff;
- while(lcd_data_port&0x80);
- lcd_en_port=0;
- }
- /*LCD1602命令字写入*/
- void lcd_command_write(uint command)
- {
- lcd_busy_wait();
- lcd_rs_port=0;
- lcd_rw_port=0;
- lcd_en_port=0;
- lcd_data_port=command;
- lcd_en_port=1;
- lcd_en_port=0;
- }
- /*LCD1602初始化*/
- void lcd_system_reset( )
- {
- lcd_delay(20);
- lcd_command_write(0x38);
- lcd_delay(100);
- lcd_command_write(0x38);
- lcd_delay(50);
- lcd_command_write(0x38);
- lcd_delay(10);
- lcd_command_write(0x08);
- lcd_command_write(0x01);
- lcd_command_write(0x06);
- lcd_command_write(0x0c);
- }
- /*LCD1602字符写入*/
- void lcd_char_write(uint x_pos,y_pos,lcd_dat)
- {
- x_pos &=0x0f;/*X位置范围 0~15*/
- y_pos &=0x01;/*Y位置范围 0~1*/
- if(y_pos==1)
- x_pos +=0x40;
- x_pos +=0x80;
- lcd_command_write(x_pos);
- lcd_busy_wait();
- lcd_rs_port=1;
- lcd_rw_port=0;
- lcd_en_port=0;
- lcd_data_port=lcd_dat;
- lcd_en_port=1;
- lcd_en_port=0;}
- /*LCD1602坏点检查*/
- void lcd_bad_check()
- {
- char i,j;
- for(i=0;i<2;i++)
- {
- for(j=0;j<16;j++)
- {
- lcd_char_write(j,i,0xff);
- }
- }
- lcd_delay(200);
- lcd_delay(200);
- lcd_delay(200);
- lcd_delay(100);
- lcd_delay(200);
- lcd_command_write(0x01);/*clearlcddisp*/
- }
- //////////////////以上是 LCD1602驱动程序////////////////
- void Delay(uint n)
- {
- uint x;
- while(n--)
- {
- x=500;
- while(x--);
- }
- }
- /*1MS为单位的延时程序*/
- void delay_1ms(uchar x)
- {
- uchar j;
- while(x--)
- {
- for(j=0;j<125;j++)
- {;}
- }
- }
- float adadverage()
- {
- float adverageval;
- unsigned char i;
- for(i=0;i<200;i++)
- {
- adverageval += GetADCResult(0);
- }
- adverageval=adverageval/200;
- return(adverageval);
- }
复制代码
所有资料51hei提供下载:
程序.rar
(33.74 KB, 下载次数: 20)
|