環境
軟件
- uVision V4.02
- ISIS Professional 7.8
芯片
- AT89C51
- ADC0809
實現效果
用電阻阻值大小控制,並用七段數碼管顯示0~500的數
相關代碼及資源
https://github.com/duganlx/DSP
操作小記
芯片介紹
ADC0809是帶有8位A/D轉換器、8路多路開關以及微處理機兼容的控制邏輯的CMOS組件。它是逐次逼近式A/D轉換器,可以和單片機直接接口。
內部邏輯結構
由上圖可知,ADC0809由一個8路模擬開關、一個地址鎖存與譯碼器、一個A/D轉換器和一個三態輸出鎖存器組成。多路開關可選通8個模擬通道,允許8路模擬量分時輸入,共用 A/D轉換器進行轉換。三態輸出鎖器用於鎖存 A/D 轉換完的數字量,當OE端爲高電平時,纔可以從三態輸出鎖存器取走轉換完的數據引腳結構
D7-D0
:8位數字量輸出引腳IN0-IN7
:8位模擬量輸入引腳VCC
:+5V工作電壓GND
:地REF(+)
:參考電壓正端REF(-)
:參考電壓負端ST
:A/D轉換啓動信號輸入端ALE
:地址鎖存允許信號輸入端EOC
:轉換結束信號輸出引腳,開始轉換時爲低電平,當轉換結束時爲高電平OE
:輸出允許控制端,用以打開三態數據輸出鎖存器CLK
:時鐘信號輸入端(一般爲500KHz)A、B、C
:地址輸入線
說明:
ST
(轉換啓動信號)
- 上跳沿:所有內部寄存器清零
- 下跳沿:開始進行A/D轉換
- 轉換期間:ST應保持低電平
EOC
(轉換結束信號)
- 高電平:表明轉換結束
- 低電平:正在進行A/D轉換
OE
(輸出允許信號)
- 爲1:輸出轉換得到的數據
- 爲0:輸出數據線呈高阻狀態
CLK
- 因ADC0809的內部沒有時鐘電路,所需時鐘信號必須由外界提供,通常使用頻率爲500KHZ
引腳端口
說明
ADC0809對輸入模擬量要求:信號單極性,電壓範圍是0-5V,若信號太小,必須進行放大;輸入的模擬量在轉換過程中應該保持不變,如若模擬量變化太快,則需在輸入前增加採樣保持電路
ALE
爲地址鎖存允許輸入線,高電平有效。當ALE
線爲高電平時,地址鎖存與譯碼器將A,B,C三條地址線的地址信號進行鎖存,經譯碼後被選中的通道的模擬量進入轉換器進行轉換。A,B和C爲地址輸入線,用於選通IN0-IN7
上的一路模擬量輸入
通道選擇表如下所示:
應用說明
- ADC0809內部帶有輸出鎖存器,可以與AT89S51單片機直接相連
- 初始化時,使ST和OE信號全爲低電平
- 送要轉換的哪一通道的地址到A,B,C端口上
- 在ST端給出一個至少有100ns寬的正脈衝信號
- 是否轉換完畢,根據
EOC
信號來判斷- 當
EOC
變爲高電平時,這時給OE
爲高電平,轉換的數據就輸出給單片機了
代碼編寫
引用庫文件
#include<reg51.h>
#include<stdio.h>
#include<stdlib.h>
#include<intrins.h>
#include<string.h>
全局變量定義
//地址鎖存
sbit ADDC=P1^6;
sbit ADDB=P1^5;
sbit ADDA=P1^4;
sbit CLK=P1^3; //clock
sbit ST=P1^2; //start (轉換啓動信號)
sbit EOC=P1^1; //end of conversion (轉換結束信號)
sbit OE=P1^0; //output enable (輸出允許信號)
//0~9
unsigned char code SEG7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
延時函數
/*
* 延時
*
* @param x 時間(不精確)
* @return
*/
void delay_ms(int i)
{
int j=0;
while(i--)
{
for(j=0;j<120;j++);
}
}
顯示
/*
* 顯示
*
* @param ADx AD轉換過後的八位數值
* @return
*/
void display(unsigned char ADx)
{
int AD = ADx*500.0/255.0;
P2=0xFD; P0=SEG7[AD/100]; delay_ms(5);//1111_1101 -> P2^1
P2=0xFB; P0=SEG7[(AD/10)%10]; delay_ms(5);//1111_1011 -> P2^2
P2=0xF7; P0=SEG7[AD%10]; delay_ms(5);//1111_0111 -> P2^3
}
說明
由下圖所示,led的2、3、4
號引腳是與端口P2.1、 P2.2、P2.3
一一連接,然後高電平表示選中,選中時,將P0
八個引腳的數據送入 led中顯示;而 led的1、2、3、4
從左到右一一對應上面的八段數碼管
初始化
/*
* 初始化
*
* @return
*/
void init()
{
// ABC=110選擇第三通道
ADDC=0;
ADDB=1;
ADDA=1;
CLK=0;
ST=1; //內部寄存器清零
EOC=1; // 轉換結束(未開始)
OE=0;
}
說明
由下圖所示,我們選擇通道3作爲輸入
中斷
/*
* 中斷
*
* @return
*/
void t0() interrupt 1
{
CLK=!CLK;
}
主函數
void main()
{
init();
//TMOD(定時器)
TMOD=0x02; //0000_0010 8位 0~255
/*
對定時器T0來說是分成兩個寄存器:TH0爲高八位,TL0爲低八位,組成了16位的定時器,
當低位TL0計滿就向高位TH0移一個數,然後清零
TH0和TL0決定採樣頻率(數值越大,頻率越高)
*/
TH0=200;
TL0=200;
EA=1; // 總中斷開關
ET0=1; // T0定時器總中斷開關
TR0=1; // 啓動T0的開定時器位
while(1)
{
//產生啓動轉換的正脈衝信號
ST=0;_nop_();ST=1;_nop_();ST=0;
while(EOC==0); //正在轉換
OE=1;
display(P3); //顯示
OE=0;
}
}
說明
ADC0809轉換完畢後,數據存放在 P3
中,所以顯示就是以 P3
作爲參數