|
本文介紹了一種以51單片機(jī)為主控器的數(shù)字電壓表。該數(shù)字電壓表采用1602液晶作為顯示部分。采用TLC1549模數(shù)轉(zhuǎn)換器將檢測(cè)到的模擬電壓值轉(zhuǎn)換為10位二進(jìn)制數(shù)據(jù)送往單片機(jī)處理。采用STC89C52單片機(jī)將接收到的二進(jìn)制數(shù)據(jù)進(jìn)行運(yùn)算處理后在液晶顯示器顯示被測(cè)電壓值。由運(yùn)放LM339和與非門74LS00構(gòu)成輸入電壓接反報(bào)警功能,超過(guò)測(cè)量量程提示功能。
該系統(tǒng)實(shí)現(xiàn)了0-50V直流電壓的測(cè)量,測(cè)量精度為0.05V。采用10位串行A/D (TLC1549)進(jìn)行模數(shù)轉(zhuǎn)換,比采用常用的8位并行A/D(ADC0809等)硬件電路更為簡(jiǎn)單,測(cè)量精度更高。1602液晶顯示器比數(shù)碼管顯示更為直觀,豐富的信息。
該系統(tǒng)只設(shè)計(jì)了測(cè)量顯示功能,由于為單片機(jī)留有豐富的I/O,所以可以方便的擴(kuò)展其他功能。
(本文系51hei單片機(jī)網(wǎng)會(huì)員jcde225原創(chuàng)。由于本人菜鳥(niǎo)一只,不足之處還請(qǐng)各位大蝦指點(diǎn)。例如顯示的電壓值最低位常在0,4,9之間跳動(dòng)。調(diào)了很久都沒(méi)解決這個(gè)問(wèn)題。) 
#include <reg52.h> //52系列頭文件 #define Disdata P1 //液晶數(shù)據(jù)端口 #define uchar unsigned char //無(wú)符號(hào)字符8位 #define uint unsigned int //無(wú)符號(hào)整數(shù)8位 uint data dis[4]={0x00,0x00,0x00,0x00};//4個(gè)數(shù)據(jù)單元和一個(gè) uchar code table[]="VOLTAGE:+ . V"; //定義初始上電液晶默認(rèn)顯示狀態(tài) uchar code table1[]="designed by :"; uchar code table3[]=" Li Xiaojun"; uchar code table2[]="SCOPE: 0-50.00V"; uchar code table4[]=" not reversed! "; sbit lcden=P3^2;//定義液晶使能端 sbit lcdrs=P3^0;//定義液晶RS端 sbit rw=P3^1;//定義液晶RW端 sbit ALE=P2^3;//定義鎖存地址控制位 sbit cs_ad=P3^5;//片選段,低電平有效 sbit dout=P3^4;//數(shù)據(jù)輸出端 sbit clk=P3^3; //轉(zhuǎn)換結(jié)束標(biāo)志位 sbit speak=P3^7;//蜂鳴器 sbit bijiao=P3^6;//接反檢測(cè)信號(hào) data int result;//測(cè)量變量暫存地址 void jiefan();//接反子函數(shù) uchar num,num1,num2,num3,num4,num5; uchar shii,gei;
//********延時(shí)函數(shù)************ void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //************* void write_com(uchar com) //液晶寫命令函數(shù) { lcdrs=0; P1=com; delay(5); lcden=1; delay(5); lcden=0; } void write_data(uchar date) //液晶寫數(shù)據(jù)函數(shù) { lcdrs=1; P1=date; delay(5); lcden=1; delay(5); lcden=0; } void write_sg(uchar add,uchar date) //寫整數(shù)位和小數(shù)位函數(shù) { uchar shi,ge; shi=date/10; //分解出一個(gè)2位數(shù)的十位 ge=date%10; write_com(0x80+add); //設(shè)置顯示位置 write_data(0x30+shi); //送去液晶顯示十位 write_data(0x30+ge); //送去液晶顯示個(gè)位 }
void init() { rw=0; lcden=0; shii=0; gei=0; write_com(0x38); //初始化1602液晶 write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); //設(shè)置顯示初始坐標(biāo)
for(num2=0;num2<13;num2++) { write_data(table1[num2]); delay(5); } write_com(0x80+40); for(num3;num3<16;num3++) { write_data(table3[num3]); delay(5); } delay(3000); }
//******************************* void scan1() { write_com(0x80); //設(shè)置顯示初始坐標(biāo) for(num=0;num<16;num++) { write_data(table[num]); delay(5); } write_sg(9,shii); write_sg(12,gei); write_com(0x80+40); for(num1;num1<16;num1++) { write_data(table2[num1]); delay(5); } write_sg(9,shii); write_sg(12,gei); } //****TLC1549轉(zhuǎn)換處理子函數(shù)********
void test()
{ data uchar i; cs_ad=1; //禁止i/o clock cs_ad=0; //開(kāi)啟控制電路,使能data out和i/o clock result=0; //清轉(zhuǎn)換變量 for(i=0;i<10;i++) //采集10次 ,即10bit { clk=0; result*=2; if(dout) result++; clk=1; } delay(590); cs_ad=1; ;;;; //data out 返回到高阻狀態(tài)而終止序列 //****數(shù)據(jù)轉(zhuǎn)換處理********** result=result*10; //結(jié)果值擴(kuò)大10倍 dis[2]=result/205; //計(jì)算整數(shù)位 dis[3]=result%205; //余數(shù)暫存 dis[3]=dis[3]*10; //計(jì)算小數(shù)第一位 dis[1]=dis[3]/205; dis[3]=dis[3]%205; dis[3]=dis[3]*10; //計(jì)算小數(shù)第二位 dis[0]=dis[3]/205; shii=dis[2]; gei=dis[1]*10+dis[0]; write_sg(9,shii); write_sg(12,gei); } //*****接反子函數(shù)********* void jiefan() { if(bijiao==0) { delay(100); if(bijiao==0) { speak=0; } else speak=1; } else { speak=1;
} } //*******主函數(shù)***** void main() { init(); scan1(); while(1) { test(); jiefan(); } }
|