基于單片機的0-24V電壓表 電路原理圖如下:
圖片1.png (3.34 MB, 下載次數: 12)
下載附件
2019-4-14 15:34 上傳
單片機源程序如下:
- #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)
2019-4-14 15:30 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|