本課題是利用單片機(jī)設(shè)計(jì)一個(gè)數(shù)字電壓表,能夠測(cè)量0-5V之間的直流電壓值,四位數(shù)碼顯示,使用的元器件數(shù)目較少。外界電壓模擬量輸入到A/D轉(zhuǎn)換部分的輸入端,通過A/D轉(zhuǎn)換變?yōu)閿?shù)字信號(hào),輸送給單片機(jī)。然后由單片機(jī)給數(shù)碼管數(shù)字信號(hào),控制其發(fā)光,從而顯示數(shù)字。
注:因?yàn)锳DC0809的通道選擇端口是使用插針,做出電路板后再用導(dǎo)線連起來的,在程序里也少了通道選擇的語句,請(qǐng)注意一下。
一.原理圖

二.仿真圖

三.存儲(chǔ)空間定義
(1)70H用于存放A/D轉(zhuǎn)換結(jié)果,71H、72H、73H、74H分別存儲(chǔ)顯示用的三位數(shù)據(jù)如表所示。 (2)地址30H~39H存放顯示在數(shù)碼管上0~9的數(shù)。如表所示。 四.程序

程序可分為數(shù)據(jù)采集系統(tǒng)、數(shù)據(jù)轉(zhuǎn)換系統(tǒng)、顯示系統(tǒng),這三部分先獨(dú)立測(cè)試,然后整體調(diào)試。
①數(shù)據(jù)采集系統(tǒng):因?yàn)锳DC0809本身并沒有內(nèi)部時(shí)鐘,需要外部時(shí)鐘來提供工作的時(shí)鐘頻率。如果利用單片機(jī)ALE端腳提供的頻率為6MHZ,而ADC0809工作的頻率在10KHZ-1MHZ。因此,需要增加含觸發(fā)器功能的器件,從面增加了系統(tǒng)的復(fù)雜程度。后來,最終用軟件編程來提供ADC0809工作的時(shí)鐘頻率,從而解決了這個(gè)問題。
②顯示系統(tǒng)的調(diào)試:要顯示的數(shù)據(jù)存放在71H、72H、73H、74H單元中,先在30H~39H分單元中存放0~9的數(shù),運(yùn)行顯示程序,進(jìn)行查表指令,察看顯示的結(jié)果是否與存放值一樣。在測(cè)試的過程中發(fā)現(xiàn)小數(shù)點(diǎn)沒有顯示,通過下面幾條指令,把小數(shù)點(diǎn)顯示出來。
MOVC A,@A+DPTR
CJNER2,#0FEH,NOT_ONE ;不是左邊第一個(gè)數(shù)碼管,則轉(zhuǎn)移
ORL A,#80H ;左邊第一個(gè)數(shù)碼管顯示小數(shù)點(diǎn)
NOT_ONE: MOVP0,A ;數(shù)碼管段選
(1) 匯編語言程序清單
QIAN EQU 71H
BAI EQU 72H
SHI EQU 73H
GEWEI EQU 74H ;71H-74H存放顯示數(shù)據(jù),依次為個(gè)位、十位、百位、千位
SHUJU EQU 70H ;地址70H存放采集數(shù)據(jù)
ST BITP3.0 ;START和ALE共用一個(gè)端口
OE BIT P3.6
EOC BIT P3.7
CLK BITP3.3
ORG 0000H
LJMP START
ORG 0030H
TAB: DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
START:
MAIN: LCALL TEST ;數(shù)據(jù)采集函數(shù)
LCALL TURNDATA ;數(shù)據(jù)處理函數(shù)
LCALL DISPLAY ;顯示函數(shù)
LJMP MAIN
DELAY: MOV R7,#06H ;約延時(shí)1.5ms
LOOP1: MOV R6,#0FFH
LOOP2: DJNZ R6,LOOP2
DJNZR7,LOOP1
RET
TEST: CLR ST
CLR OE
SETB ST
CLR ST ;ST端口下降沿,開始轉(zhuǎn)換
LOOPCLK: SETBCLK ;由軟件來提供ADC0809工作的時(shí)鐘頻率
CLR CLK
JNB EOC,LOOPCLK ;EOC=1時(shí),退出循環(huán)
SETBOE ;轉(zhuǎn)換后數(shù)據(jù)的傳送
MOV P1,#0FFH ;P1端口讀數(shù)據(jù),需先給高電平
MOV A,P1
CLR OE
MOV SHUJU,A ;存儲(chǔ)數(shù)據(jù)到地址70H
RET
TURNDATA:
MOV A,SHUJU
MOV B,#51
DIV AB ;余數(shù)在B,相除以后C=0
MOV QIAN,A ;儲(chǔ)存千位
CLR F0
MOV A,B
SUBBA,#1AH ;A減去26,測(cè)試上面AB相除時(shí),余數(shù)與26相比較
MOV F0,C ;余數(shù)<26,則C=1,不用加5調(diào)整
MOV A,#10
MUL AB
MOV B,#51
DIV AB
JB F0,LP1
ADD A,#5 ;若AB相除后B>=26,百位加五
LP1: MOV BAI,A ;儲(chǔ)存百位
CLR F0
MOV A,B
SUBBA,#1AH
MOV F0,C
MOV A,#10
MUL AB
MOV B,#51
DIV AB
JB F0,LP2 ;F0=1時(shí),轉(zhuǎn)移
ADD A,#5 ;若AB相除后B>=26,十位加五
LP2: MOV SHI,A ;儲(chǔ)存十位
CLR F0
MOV A,B
SUBBA,#1AH
MOV F0,C
MOV A,#10
MUL AB
MOV B,#51
DIV AB
JB F0,LP3 ;F0=1時(shí),轉(zhuǎn)移
ADD A,#5 ;若AB相除后B>=26,個(gè)位加五
LP3: MOV GEWEI,A ;儲(chǔ)存?zhèn)位
RET
DISPLAY:
MOV R1,#4 ;循環(huán)四次
MOV R2,#0FEH
MOV R0,#71H ;存放顯示初始地址
XIANSHI:
MOV DPTR,#TAB
MOVA,@R0
MOVCA,@A+DPTR
CJNER2,#0FEH,NOT_ONE ;不是左邊第一個(gè)數(shù)碼管,則轉(zhuǎn)移
ORL A,#80H ;左邊第一個(gè)數(shù)碼管顯示小數(shù)點(diǎn)
NOT_ONE: MOVP0,A ;數(shù)碼管段選
MOVP2,R2 ;數(shù)碼管位選
LCALLDELAY ;延時(shí)
MOV A,R2
RL A ;循環(huán)左移
MOV R2,A
INCR0 ;選取下一個(gè)地址
DJNZ R1,XIANSHI
RET
END
(2) C語言程序清單
#include<reg51.h>
sbit CLK=P3^3;
sbit OE=P3^6;
sbit ST=P3^0;
sbit EOC=P3^7;
unsigned int dianya;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(unsigned int z)
{
while(z--);
}
void ADC_0809()
{
unsignedchar temp=2;
ST=0;
OE=0;
ST=1;
ST=0;
CLK=1;
CLK=0;
CLK=1;
CLK=0;
while(!EOC)
{
CLK=1;
CLK=0;
}
OE=1;
P1=0xff; //讀取P1端口數(shù)據(jù)
temp=P1;
dianya=(unsigned int)temp*19.53;
OE=0;
}
void Vpp_Show()
{
unsignedchar qian,bai,shi,ge;
qian=dianya/1000;
bai=dianya00/100;
shi=dianya0/10;
ge=dianya;
P2=0xfe;
P0=table[qian]|0x80; //顯示小數(shù)點(diǎn)
delay(50);
P2=0xfd;
P0=table[bai];
delay(50);
P2=0xfb;
P0=table[shi];
delay(50);
P2=0xf7;
P0=table[ge];
}
void main()
{
while(1)
{
ADC_0809();
Vpp_Show();
}
}
(技術(shù)部)
|