一. 實驗器件介紹
1. ADC0804芯片介紹
ADC0804是一個8位CMOS型逐次比較式A/D轉(zhuǎn)換器,具有三態(tài)鎖存輸出功能,最短轉(zhuǎn)換時間為100us,其芯片實物圖和引腳圖如下:
CS:片選信號,低電平有效;
RD:外部讀取轉(zhuǎn)換結(jié)果的控制信號,當RD為高電平時,DB0-DB7為高阻態(tài);當RD為低電平
時,數(shù)據(jù)才會通過DB0-DB7輸出; WR:A/D轉(zhuǎn)換器啟動控制信號,當WR由高電平變?yōu)榈碗娖綍r,轉(zhuǎn)換器被清零,當WR由低電平變?yōu)楦唠娖綍r,A/D轉(zhuǎn)換正式開始;
CLK IN和CLK R:時鐘輸入端,在ADC0804片內(nèi)有時鐘發(fā)生器,采用內(nèi)部時鐘時,在CLK IN CLK R 和地線之間連接RC電路即可,ADC0804的工作頻率約為100-1460khz,若使RC
電路作為時鐘,其振蕩頻率為1/(1.1RC); INTR:中斷請求輸出信號,當A/D轉(zhuǎn)換結(jié)束時,INTR引腳輸出低電平,只有當數(shù)據(jù)被取走后(單片機發(fā)出讀數(shù)據(jù)指令),此引腳才會變?yōu)楦唠娖剑?/p>
VIN+和VIN-:差動模擬電壓輸入端,若輸入為單端正電壓,VIN-應接地,若差動輸入,則輸入信號直接加入VIN+和VIN-;
AGND.DGND:模擬信號地與數(shù)字信號地,若系統(tǒng)對抗干擾要求嚴格,則這兩條地線必須分接地;
VREF/2:參考電壓值的一半,若在ADC0804組成的電路中需要的參考電壓為5V,則此引腳
可以懸空。若電路中需要使用的參考電壓小于5V,即參考電壓值的一半小于2.5V,這時可將此引腳連接到需要的參考電壓值(如4V)的 1/2電壓值上(如 2V),在ADC0804芯片內(nèi)部會自動判斷參考電壓的選擇,當VREF/2引腳的電壓值低于2.5V時,芯片會自動選擇由VREF/2引腳電壓放大2倍以后的電壓值作為參考電壓。
DB0-DB7:8位數(shù)字輸出端。
2. LCD1602液晶介紹
1602字符型LCD有16個引腳,其芯片實物圖和引腳圖如下:
1602字符型LCD具有較豐富的指令集,如下表:
下面介紹LCD1602引腳功能:
VSS:電源地;
VDD:+5V邏輯電源;
VEE:液晶驅(qū)動電源;
RS:寄存器選擇(RS=1,數(shù)據(jù);RS=0,命令);
R/W:讀。寫操作選擇(R/W=1,讀;R/W=0,寫);
E:使能信號;
DB0-DB7:數(shù)據(jù)總線;
Black2:背光電源地線;
二. 數(shù)字電壓表仿真圖
三. 實驗設(shè)計原理
1. 實驗硬件設(shè)備:LCD1602液晶顯示器一塊,ADC0804芯片一片,兩個滑動變阻器,一個150pF電容,兩個200歐姆的電阻,一個10K歐姆的電阻,STC89C51芯片,電源,地線,按鍵(復位電路和晶振電路另加),杜邦線諾干。
2. ADC0804在使用時,外圍電壓的連接比較簡單,只需要對參考電壓和時鐘輸入端進行設(shè)計即可。通常情況下,時鐘的輸入可以選用RC諧振電路,ADC0804可以進行A/D轉(zhuǎn)換的時鐘頻率為100—1460KHZ,典型值為640KHZ,這里選用R=10K歐姆.C=150PF的諧振電路,利用公式1/(1.1RC)計算后,此時的時鐘頻率約為606KHZ,與典型值十分接近。
3. 模擬電壓的計算:這里選用的是8位A/D轉(zhuǎn)換器,數(shù)值的變化范圍是0—255(00H-FFH),模擬電壓的輸入范圍是0-5V,每個數(shù)碼的變化,對應的電壓值的變化為0.0196V,所以要計算模擬電壓值,就可以利用下面的公式進行計算: V=D*0.0196
4. 克服浮點運算方法:從上式不難看出,在計算過程,需要乘以一個0.0196,這是一個小數(shù),在計算機中稱為浮點數(shù)。而對于8位單片機來說,不具有浮點運算能力,如果一定要計算浮點數(shù),將占用單片機中大量的內(nèi)存單元和CPU時間。這里采用一種簡單的方法:就是將從A/D讀取進來的數(shù)字量直接乘以196,即進行整數(shù)運算,運算結(jié)果是真正值的1000倍,這個整數(shù)運算的速度是非常快的,不會占用過多的CPU時間。由于是兩個8位的二進制數(shù)相乘,得到的結(jié)果不會超過16位二進制數(shù)。
5. 電壓值的顯示:最常用到的二進制轉(zhuǎn)換成BCD碼的方法是用除法。先用得到的16位二進制數(shù)除以10000,得到的商就是模擬電壓值的整數(shù)部分(模擬電壓的輸入為0-5V,所以整數(shù)部分只有1位),得到的余數(shù)是模擬電壓值的小數(shù)部分;接下來用余數(shù)除以1000,商是十分位,余數(shù)作為被除數(shù)再除以100,商為百分位,余數(shù)再除以10,商為千分位。這樣就將16位的二進制數(shù)轉(zhuǎn)換成了4位BCD碼。
四. 數(shù)字電壓表C語言程序
//珞珈09級通信單片機實驗 《AD轉(zhuǎn)換器設(shè)計數(shù)字電壓表》
#include《reg51.h》
#define uchar unsigned char
#define uint unsigned int
sbit lcd_rs=P2^0; sbit lcd_en=P2^1;
sbit cs=P2^7; //AD片選 sbit rd=P2^6; sbit wr=P2^5;
sbit INTR=P3^2;//中斷請求信號 uint temp,D1,D2,D3,D4; uint shu;
uint AD_read();
void delay(uint z);
void write_com(uchar com); void write_date(uchar date); void lcd_init();
void display(uchar qian,uchar bai,uchar shi,uchar ge); void AD_init(); void AD_start();
void main() {
write_com(0x01);//清屏 lcd_init(); AD_init (); while(1) {
AD_start();
while(INTR==1);//AD轉(zhuǎn)換是否結(jié)束,結(jié)束為低電平
INTR=0;
shu=AD_read(); shu=shu*196;
D1=shu/10000;//整數(shù)部分,0.0196v是最小變化量 shu=shu%10000;
D2=shu/1000;//十分位數(shù) shu=shu%1000;
D3=shu/100;//百分位數(shù)
shu=shu%100;
D4=shu/10;//千分位數(shù)
display(D1,D2,D3,D4);//顯示LcD1602
}
}
void delay(uint z) {
uint x,y;
for(x=z;x》0;x--)
for(y=110;y》0;y--);
}
void write_com(uchar com) {
P0=com;
lcd_rs=0;
lcd_en=1;
lcd_en=0;
delay(2);
}
void write_shu(uchar shu)
{
P0=shu;
lcd_rs=1;
lcd_en=1;
lcd_en=0;
delay(5); }
void lcd_init() {
lcd_en=0;
write_com(0x01);//清屏
write_com(0x06);//指針加減與移動
write_com(0x0c);//光標
write_com(0x38);//液晶初始化命令 }
void display(uchar qian,uchar bai,uchar shi,uchar ge) {
write_com(0x80+0x02);
write_shu(‘G’);
write_com(0x80+0x03);
write_shu(‘u’);
write_com(0x80+0x04);
write_shu(‘o’);
write_com(0x80+0x06);
write_shu(‘L’);
write_com(0x80+0x07);
write_shu(‘v’);
write_com(0x80+0x09);
write_shu(‘C’);
write_com(0x80+0x0a);
write_shu(‘h’);
write_com(0x80+0x0b);
write_shu(‘a(chǎn)’);
write_com(0x80+0x0c);
write_shu(‘o’);
write_com(0x80+0x44);
write_shu(0x30+qian);//0x30代表數(shù)字0
write_com(0x80+0x45);
write_shu(‘?!?
write_com(0x80+0x46);
write_shu(0x30+bai);
write_com(0x80+0x47);
write_shu(0x30+shi);
write_com(0x80+0x48);
write_shu(0x30+ge);
write_com(0x80+0x49);
write_shu(‘V’);
}
void AD_init()//AD初始化函數(shù) {
cs=1; wr=1; rd=1; }
void AD_start()//AD啟動 {
P1=0xff; cs=0;//開 wr=0;
wr=1;//寫完后關(guān)閉 cs=1; }
uint AD_read() {
cs=0; rd=0; delay(1);
temp=P1;
rd=1;
cs=1;
return(temp); }
評論
查看更多