本課題是利用單片機設計一個數字電壓表,能夠測量0-5V之間的直流電壓值,四位數碼顯示,使用的元器件數目較少。外界電壓模擬量輸入到A/D轉換部分的輸入端,通過A/D轉換變為數字信號,輸送給單片機。然后由單片機給數碼管數字信號,控制其發光,從而顯示數字。
注:因為ADC0809的通道選擇端口是使用插針,做出電路板后再用導線連起來的,在程序里也少了通道選擇的語句,請注意一下。
一.原理圖

二.仿真圖

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

程序可分為數據采集系統、數據轉換系統、顯示系統,這三部分先獨立測試,然后整體調試。
①數據采集系統:因為ADC0809本身并沒有內部時鐘,需要外部時鐘來提供工作的時鐘頻率。如果利用單片機ALE端腳提供的頻率為6MHZ,而ADC0809工作的頻率在10KHZ-1MHZ。因此,需要增加含觸發器功能的器件,從面增加了系統的復雜程度。后來,最終用軟件編程來提供ADC0809工作的時鐘頻率,從而解決了這個問題。
②顯示系統的調試:要顯示的數據存放在71H、72H、73H、74H單元中,先在30H~39H分單元中存放0~9的數,運行顯示程序,進行查表指令,察看顯示的結果是否與存放值一樣。在測試的過程中發現小數點沒有顯示,通過下面幾條指令,把小數點顯示出來。
MOVC A,@A+DPTR
CJNER2,#0FEH,NOT_ONE ;不是左邊第一個數碼管,則轉移
ORL A,#80H ;左邊第一個數碼管顯示小數點
NOT_ONE: MOVP0,A ;數碼管段選
(1) 匯編語言程序清單
QIAN EQU 71H
BAI EQU 72H
SHI EQU 73H
GEWEI EQU 74H ;71H-74H存放顯示數據,依次為個位、十位、百位、千位
SHUJU EQU 70H ;地址70H存放采集數據
ST BITP3.0 ;START和ALE共用一個端口
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 ;數據采集函數
LCALL TURNDATA ;數據處理函數
LCALL DISPLAY ;顯示函數
LJMP MAIN
DELAY: MOV R7,#06H ;約延時1.5ms
LOOP1: MOV R6,#0FFH
LOOP2: DJNZ R6,LOOP2
DJNZR7,LOOP1
RET
TEST: CLR ST
CLR OE
SETB ST
CLR ST ;ST端口下降沿,開始轉換
LOOPCLK: SETBCLK ;由軟件來提供ADC0809工作的時鐘頻率
CLR CLK
JNB EOC,LOOPCLK ;EOC=1時,退出循環
SETBOE ;轉換后數據的傳送
MOV P1,#0FFH ;P1端口讀數據,需先給高電平
MOV A,P1
CLR OE
MOV SHUJU,A ;存儲數據到地址70H
RET
TURNDATA:
MOV A,SHUJU
MOV B,#51
DIV AB ;余數在B,相除以后C=0
MOV QIAN,A ;儲存千位
CLR F0
MOV A,B
SUBBA,#1AH ;A減去26,測試上面AB相除時,余數與26相比較
MOV F0,C ;余數<26,則C=1,不用加5調整
MOV A,#10
MUL AB
MOV B,#51
DIV AB
JB F0,LP1
ADD A,#5 ;若AB相除后B>=26,百位加五
LP1: MOV BAI,A ;儲存百位
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時,轉移
ADD A,#5 ;若AB相除后B>=26,十位加五
LP2: MOV SHI,A ;儲存十位
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時,轉移
ADD A,#5 ;若AB相除后B>=26,個位加五
LP3: MOV GEWEI,A ;儲存個位
RET
DISPLAY:
MOV R1,#4 ;循環四次
MOV R2,#0FEH
MOV R0,#71H ;存放顯示初始地址
XIANSHI:
MOV DPTR,#TAB
MOVA,@R0
MOVCA,@A+DPTR
CJNER2,#0FEH,NOT_ONE ;不是左邊第一個數碼管,則轉移
ORL A,#80H ;左邊第一個數碼管顯示小數點
NOT_ONE: MOVP0,A ;數碼管段選
MOVP2,R2 ;數碼管位選
LCALLDELAY ;延時
MOV A,R2
RL A ;循環左移
MOV R2,A
INCR0 ;選取下一個地址
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端口數據
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; //顯示小數點
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();
}
}
(技術部)
|