自制單片機(jī)之十一……模數(shù)轉(zhuǎn)換IC ADC0809
我們重在實際制做,太羅嗦的內(nèi)容我就不說了,只講些跟制做有關(guān)的最精煉的知識。
ADC0809是可以將我們要測量的模擬電壓信號量轉(zhuǎn)換為數(shù)字量從而可以進(jìn)行存儲或顯示的一種轉(zhuǎn)換IC。
下面是它的管腳圖和邏輯圖:
管腳功能說明:
IN0-IN7:模擬量輸入通道。就是說它可以分時地分別對八個模擬量進(jìn)行測量轉(zhuǎn)換。
ADDA-C:地址線。也就是通過這三根地址線的不同編碼來選擇對哪個模擬量進(jìn)行測量轉(zhuǎn)換。
ALE:地址鎖存允許信號。在低電平時向ADDA-C寫地址,當(dāng)ALE跳至高電平后ADDA-C上的數(shù)據(jù)被鎖存
START:啟動轉(zhuǎn)換信號。當(dāng)它為上升沿后,將內(nèi)部寄存器清0。當(dāng)它為下降沿后,開始A/D轉(zhuǎn)換。
D0-D7:數(shù)據(jù)輸出口。轉(zhuǎn)換后的數(shù)字?jǐn)?shù)據(jù)量就是從這輸出給S52的。
OE:輸出允許信號,是對D0-D7的輸出控制端,OE=0,輸出端呈高阻態(tài),OE=1,輸出轉(zhuǎn)換得到的數(shù)據(jù)。
CLOCK:時種信號。ADC0809內(nèi)部沒有時鐘電路,需由外部提供時鐘脈沖信號。一般為500KHz
EOC:轉(zhuǎn)換結(jié)束狀態(tài)信號。EOC=0,正在進(jìn)行轉(zhuǎn)換。EOC=1,轉(zhuǎn)換結(jié)束,可以進(jìn)行下一步輸出操作
REF(+)、REF(-):參考電壓。參考電壓用來與輸入的模擬量進(jìn)行比較,作為測量的基準(zhǔn)。一般REF(=)=5v REF(-)=0V。
下面我先給出ADC0809的時序圖再說說它的工作過程:
它的工作過程是這樣的,
?、僭贗N0-IN7上可分別接上要測量轉(zhuǎn)換的8路模擬量信號。有人問了,可不可以只接一路?我就只想測一個模擬信號。當(dāng)然可了,能挑一百斤的擔(dān)子,讓你只挑十斤那還不小菜。廢話太多。。STOP。
②將ADDA-ADDC端給上代表選擇測量通道的代碼。如000(B)則代表通道0;001(B)代表通道1;111則代表通道7。
③將ALE由低電平置為高電平,從而將ADDA-ADDC送進(jìn)的通道代碼鎖存,經(jīng)譯碼后被選中的通道的模擬量送給內(nèi)部轉(zhuǎn)換單元。
④給START一個正脈沖。當(dāng)上升沿時,所有內(nèi)部寄存器清零。下降沿時,開始進(jìn)行A/D轉(zhuǎn)換;在轉(zhuǎn)換期間,START保持低電平。
⑤EOC為轉(zhuǎn)換結(jié)束信號。在上述的A/D轉(zhuǎn)換期間,可以對EOC進(jìn)行不斷測量,當(dāng)EOC為高電平時,表明轉(zhuǎn)換工作結(jié)束。否則,表明正在進(jìn)行A/D轉(zhuǎn)換。
?、蕻?dāng)A/D轉(zhuǎn)換結(jié)束后,將OE設(shè)置為1,這時D0-D7的數(shù)據(jù)便可以讀取了。OE=0,D0-D7輸出端為高阻態(tài),OE=1,D0-D7端輸出轉(zhuǎn)換的數(shù)據(jù)。
說明:ADC0809的轉(zhuǎn)換工作是在時鐘脈沖的條件下完成的,因此首先要在CLOCK端給它一個時鐘信號,說明書上給出了可以接入的脈沖信號頻率是在10KHz-1280KHz,典型值是640KHz。
時序圖上的teoc時長為,從START上升沿開始后的8個時鐘同期再加2微秒。這一點得注意,因為當(dāng)START脈沖剛結(jié)束進(jìn)入轉(zhuǎn)換工作時,EOC還沒有立即變?yōu)榈碗娖蕉沁^了8個時鐘周期后才進(jìn)入低電平的,所以再給出START脈沖后最好延時一會再進(jìn)行EOC的檢測。
一個通道的轉(zhuǎn)換時間一般為64個時鐘周期,如時鐘頻率為640KHz時,時鐘周期為1.5625微秒,一個通道的轉(zhuǎn)換時間則為1.5625×64=100微秒,那么1秒種就可以轉(zhuǎn)換1000000÷100=10000次。
下面我們給出一個教材上經(jīng)典的接線圖再說明它的利弊:
這是個老教材上的圖紙,網(wǎng)絡(luò)查查也大都是這樣的圖,它的時鐘脈沖是通過C51的ALE經(jīng)過2分頻得到的,它一般是指,當(dāng)C51的晶振為6MHz時,ALE輸出1MHz的脈沖,經(jīng)2分頻后得到500KHz。但這對我們現(xiàn)在S52上使用12MHz晶振時就不適用了?,F(xiàn)在S52的ALE輸出的脈沖為2MHz,2分頻后也有1MHz。
網(wǎng)上查了一下,補(bǔ)救的辦法基本上是用T0時鐘來模擬出個10KHz的脈沖信號。這是ADC0809時鐘脈沖允許的最小值。也的確,一般我們用不著那么快的轉(zhuǎn)換速度,所以給個10KHz也夠了,還省掉了一個分頻器。不過這也基本上是用T0能模擬出的最高頻率了,
sbit CLK=P3^3;
void main(void)
{
ET0=1;
EA=1;
TMOD=0X12;
TH0=216;
TL0=216;
TR0=1;
...
}
void t0(void) interrupt 1
{
CLK=~CLK;
}
從上面的程序可以看出,每40個時鐘脈沖就發(fā)生一次中斷。S51基本上也就一直忙著中斷處理了。中斷太頻繁,占資源。
我們來看看D0-D7輸出口,它是只能輸出不能寫入的,而ADDA-ADDC又是只能寫入而不能輸出的,因此我們可以將74HC373也省掉。同樣74LS02也自然可以不用了。
這樣我們省去了所有的其它門電路IC,也包括那個HC373。
簡化電路為的是使ADC0809在用最少的其它門電路而使它工作,讓我們能專注學(xué)習(xí)ADC0809是如何工作過程的。現(xiàn)在我來說說如何更好的模擬出這個時鐘。我們現(xiàn)在用的都是S52芯片了,不知道大家用過里面的T2時鐘嗎?它有個時鐘輸出功能,如下圖:
根據(jù)公式,用12MHz的晶振,就可以在P1.0輸出45Hz----3MHz頻率的時鐘脈沖,要輸出500KHz的脈沖還不小意思呀。
我試驗了一下T2時鐘,很好用:
/*這個程序讓AT89S52的T2時鐘從P1.0口輸出45HZ方波脈沖,P1.0口接到P3.4口作為
T0的外部計數(shù),通過T0的時鐘中斷在P2口輸出。T0每45個脈沖就中斷一次,也就是剛好一秒一次*/
#include
void main()
{
/* T2 設(shè)置 */
TR2=0x0;
T2MOD=0x02; //0010(B) 設(shè)置T2為P1.0口輸出方波模式
C_T2=0; //用內(nèi)部時鐘計數(shù)
TL2=0x0;
TH2=0x0;
RCAP2L=0x0;
RCAP2H=0x0;
/* T0 設(shè)置 */
TMOD=0x6; //0110(B),T0為外部計數(shù)模式,方式為2 (8位自動裝載)
EA=1;//總中斷允許
ET0=1;//T0中斷允許
TH0=256-45;
TL0=256-45;
/*start timer */
TR0=1; //啟動T0時鐘
TR2=1; //啟動T2時鐘
do
{
}while(1);
}
void t0(void) interrupt 1//T0中斷服務(wù)程序
{
P2=~P2;
}
其結(jié)果P1.0輸出45Hz的脈沖,T0的中斷是以P1.0的45個脈沖發(fā)生一次的。P2口的數(shù)碼管以一秒的時間亮,一秒時間熄滅的在閃爍,T2定時器看來很好用。達(dá)到要求。
好!上面的程序只是試試S52的T2定時器是否可正常使用。言歸正傳我們還是來談ADC0809的電路:見下圖:
電路圖比較簡單,我就不另畫了,就將這張電圖板圖貼上。D0-D7是數(shù)據(jù)讀取位,同時在低三位D0-D2上也分別接上了A、B、C通道選擇位。CLK為ADC0809所需的時鐘脈沖,我們將要用T2來給出時鐘脈沖,因此我們必須把CLK接在S52的P1.0上。這樣OE、EOC、ST就分別順著接P1.1、P1.2