仿真版本:proteus 7.8
程序編譯器:keil 4/keil 5
編程語言:C語言
設計編號:S0006
設計說明:
1、利用51單片機作為主控芯片,模擬量輸入范圍直流0v-5v。模擬量經A/D(ADC0809)模數(shù)轉換芯片,把模擬量轉換為數(shù)字量輸入到單片機的P0口,再由單片機控制LCD1602液晶顯示模擬量輸入的電壓值。
2、此次設計的是數(shù)字電壓表,要求的電壓范圍是0~5v。
3、系統(tǒng)設計主要包括四個部分:
分別是電源模塊、AD模數(shù)轉換部分、51單片機最小系統(tǒng)部分、數(shù)碼管顯示部分。
首先由單片機初始化ADC0809模數(shù)轉換芯片和共陰數(shù)碼管顯示,當外接被測電壓后,ADC0809將模擬電壓信號轉換為數(shù)字信號輸入到單片機的I/O口,通過單片機處理后將電壓的大小顯示在LCD1602液晶上面。
仿真圖
以AT89C51單片機為核心,起著控制作用。系統(tǒng)包括LCD1602液晶顯示電路、復位電路、時鐘電路、模數(shù)轉換電路電路。設計思路分為五個模塊:復位電路、晶振電路模塊、AT89C51、LCD1602液晶顯示電路、模數(shù)轉換器電路這五個模塊。
設計框圖
ADC0809
ADC0809是美國國家半導體公司生產的CMOS工藝8通道,8位逐次逼近式AD轉換器。其內部有一個8通道多路開關,它可以根據(jù)地址碼鎖存譯碼后的信號,只選通8路模擬輸入信號中的一個進行A/D轉換。
(1)主要特性:
1)8路輸入通道,2位A/D轉換器,即分辨率為8位。
2)具有轉換起??刂贫?。
3)轉換時間為100μs(時鐘為640kHz時),130μs(時鐘為500kHz時)
4)單個+5V電源供電
5)模擬輸入電壓范圍0~+5V,不需零點和滿刻度校準。
6)工作溫度范圍為-40~+85攝氏度
7)低功耗,約15mW。
51單片機最小系統(tǒng)
單片機最小系統(tǒng)說明:
時鐘信號的產生:在MCS-51芯片內部有一個高增益反相放大器,其輸入端為芯片引腳XTAL1,其輸出端為引腳XTAL2。而在芯片的外部,XTAL1和XTAL2之間跨接晶體振蕩器和微調電容,從而構成一個穩(wěn)定的自激振蕩器,這就是單片機的時鐘振蕩電路。
時鐘電路產生的振蕩脈沖經過觸發(fā)器進行二分頻之后,才成為單片機的時鐘脈沖信號。
一般地,電容C2和C3取30pF左右,晶體的振蕩頻率范圍是1.2-12MHz。如果晶體振蕩頻率高,則系統(tǒng)的時鐘頻率也高,單片機的運行速度也就快。
單片機復位使CPU和系統(tǒng)中的其他功能部件都處在一個確定的初始狀態(tài)下,并從這個狀態(tài)開始工作。單片機復位條件:必須使9腳加上持續(xù)兩個機器周期(即24個振蕩周期)的高電平。
原理圖
PCB:
軟件設計
該系統(tǒng)由延時子函數(shù)、LCD1602液晶忙檢測子函數(shù)、LCD1602液晶寫命令/寫數(shù)據(jù)子函數(shù)、漢字顯示子函數(shù)、LCD1602液晶顯示字符串子函數(shù)、LCD1602液晶初始化子函數(shù)、ADC0809轉換子函數(shù)、主函數(shù)和數(shù)據(jù)定義這幾部分組成。
程序代碼:
main函數(shù)
//<程序名>:數(shù)字電壓表 **
//<功能>:使用LCD顯示被檢測電壓,精度為0.05V,范圍是0~5V。 **
#include"includes.h"
#define TIME0H 0x3C
#define TIME0L 0xB0
uchar uc_Clock=0; //定時器0中斷計數(shù)
bit b_DATransform=0;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把電壓顯示在LCD上>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vShowVoltage(uint uiNumber)
{
uchar ucaNumber[3],ucCount;
if(uiNumber>999)
uiNumber=999;
ucaNumber[0]=uiNumber/100; //把計算數(shù)字的每個位存入數(shù)組。
ucaNumber[1]=(uiNumber-100*(int)ucaNumber[0])/10;
ucaNumber[2]=uiNumber-100*(int)ucaNumber[0]-10*ucaNumber[1];
for(ucCount=0;ucCount<3;ucCount++)
{
vShowOneChar(ucaNumber[ucCount]+48); //從首位到末位逐一輸出。
if(ucCount==0)
vShowOneChar('.');
}
}
//*************************************************************************************************
//* *
//* ********************************主函數(shù)****************************** *
//* *
//*************************************************************************************************
void main()
{
TMOD=0x01; //定時器0,模式1。
TH0=TIME0H;
TL0=TIME0L;
TR0=1; //啟動定時器。
ET0=1; //開定時器中斷。
EA=1; //開總中斷
vdInitialize();
vWriteCMD(0x84); //寫入顯示起始地址(第一行第4個位置)
vShowChar("voltage");
vWriteCMD(0xC9);
vShowChar("(V)");
while(1)
{
if(b_DATransform==1)
{
b_DATransform=0;
vWriteCMD(0xC4);
vShowVoltage(uiADTransform());
}
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定時器0中斷函數(shù)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void t0() interrupt 1
{
if(uc_Clock==0)
{
uc_Clock=5;
b_DATransform=1;
}
else
uc_Clock--;
TH0=TIME0H; //恢復定時器0。
TL0=TIME0L;
}
LCD1602驅動程序
#include"LCD1602.h"
void vWriteCMD(uchar ucCommand)
{
vDelay(); //先延時。
LCDE=1; //然后把LCD改為寫入命令狀態(tài)。
LCDRS=0;
LCDRW=0;
LCDPORT=ucCommand; //再輸出命令。
LCDE=0; //最后執(zhí)行命令。
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把1個數(shù)據(jù)寫入LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vWriteData(uchar ucData)
{
vDelay(); //先延時。
LCDE=1; //然后把LCD改為寫入數(shù)據(jù)狀態(tài)。
LCDRS=1;
LCDRW=0;
LCDPORT=ucData; //再輸出數(shù)據(jù)。
LCDE=0; //最后顯示數(shù)據(jù)。
}
void vShowOneChar(uchar ucChar)
{
switch(ucChar)
{
case ' ': vWriteData(0x20);break;
case '!': vWriteData(0x21);break;
case '"': vWriteData(0x22);break;
case '#': vWriteData(0x23);break;
case '$': vWriteData(0x24);break;
case '%': vWriteData(0x25);break;
case '&': vWriteData(0x26);break;
case '>': vWriteData(0x27);break;
case '(': vWriteData(0x28);break;
case ')': vWriteData(0x29);break;
case '*': vWriteData(0x20);break;
case '+': vWriteData(0x2A);break;
case '-': vWriteData(0x2D);break;
case '/': vWriteData(0x2F);break;
case '=': vWriteData(0x3D);break;
case '<': vWriteData(0x3E);break;
case '?': vWriteData(0x3F);break;
case '.': vWriteData(0x2E);break;
case ':': vWriteData(0x3A);break;
case '0': vWriteData(0x30);break;
case '1': vWriteData(0x31);break;
case '2': vWriteData(0x32);break;
case '3': vWriteData(0x33);break;
case '4': vWriteData(0x34);break;
case '5': vWriteData(0x35);break;
case '6': vWriteData(0x36);break;
case '7': vWriteData(0x37);break;
case '8': vWriteData(0x38);break;
case '9': vWriteData(0x39);break;
case 'A': vWriteData(0x41);break;
case 'B': vWriteData(0x42);break;
case 'C': vWriteData(0x43);break;
case 'D': vWriteData(0x44);break;
case 'E': vWriteData(0x45);break;
case 'F': vWriteData(0x46);break;
case 'G': vWriteData(0x47);break;
case 'H': vWriteData(0x48);break;
case 'I': vWriteData(0x49);break;
case 'J': vWriteData(0x4A);break;
case 'K': vWriteData(0x4B);break;
case 'L': vWriteData(0x4C);break;
case 'M': vWriteData(0x4D);break;
case 'N': vWriteData(0x4E);break;
case 'O': vWriteData(0x4F);break;
case 'P': vWriteData(0x50);break;
case 'Q': vWriteData(0x51);break;
case 'R': vWriteData(0x52);break;
case 'S': vWriteData(0x53);break;
case 'T': vWriteData(0x54);break;
case 'U': vWriteData(0x55);break;
case 'V': vWriteData(0x56);break;
case 'W': vWriteData(0x57);break;
case 'X': vWriteData(0x58);break;
case 'Y': vWriteData(0x59);break;
case 'Z': vWriteData(0x5A);break;
case 'a': vWriteData(0x61);break;
case 'b': vWriteData(0x62);break;
case 'c': vWriteData(0x63);break;
case 'd': vWriteData(0x64);break;
case 'e': vWriteData(0x65);break;
case 'f': vWriteData(0x66);break;
case 'g': vWriteData(0x67);break;
case 'h': vWriteData(0x68);break;
case 'i': vWriteData(0x69);break;
case 'j': vWriteData(0x6A);break;
case 'k': vWriteData(0x6B);break;
case 'l': vWriteData(0x6C);break;
case 'm': vWriteData(0x6D);break;
case 'n': vWriteData(0x6E);break;
case 'o': vWriteData(0x6F);break;
case 'p': vWriteData(0x70);break;
case 'q': vWriteData(0x71);break;
case 'r': vWriteData(0x72);break;
case 's': vWriteData(0x73);break;
case 't': vWriteData(0x74);break;
case 'u': vWriteData(0x75);break;
case 'v': vWriteData(0x76);break;
case 'w': vWriteData(0x77);break;
case 'x': vWriteData(0x78);break;
case 'y': vWriteData(0x79);break;
case 'z': vWriteData(0x7A);break;
default: break;
}
}
void vShowChar(uchar ucaChar[])
{
uchar ucCount;
for(ucCount=0;;ucCount++)
{
vShowOneChar(ucaChar[ucCount]);
if(ucaChar[ucCount+1]=='?')
break;
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<延時函數(shù)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vDelay()
{
uint uiCount;
for(uiCount=0;uiCount<250;uiCount++);
}
設計報告:
資料清單
設計報告:
[外鏈圖片轉存中...(img-aKFWFwGA-1662131075048)]
## 資料清單
[外鏈圖片轉存中...(img-QQcTNJPP-1662131075048)]
[資料下載鏈接](https://docs.qq.com/doc/DS1ZJcG1MSHNGUnRS)