ADC分成個部份,一個是利用8051控制實習板上的一組串列8位元ADC ,一個是直接使用笙泉82G516內建之10位元ADC,解析度更高,又省略了外接IC的麻煩。
1.ADC0831控制 (ADC0831資料手冊)
ADC8031為一8位元類比到數位轉換器,只有8支接腳,具有一組電壓輸入,透過AD轉換成8位元數位值,微控制器讀取轉換結果,只需透過3之接腳,非常方便,VREF為參考電壓,通常直接接到VCC,VIN(-)為負電壓,通常直接接到GND,在此情下下,若輸入電壓VIN(+) = VCC時,讀回值為255,其他轉換值,可由以下計算是求得
轉換值 =( VIN(+) / VCC) * 255
若要由讀值反推回去電壓,則 VIN(+) = (轉換值//255) * VCC
這顆IC只有一組電壓輸入,不須寫入命令選擇讀取哪一通道,只要開始轉換其讀取轉換結果就可以了,控制較簡單,相關控制時脈波形要求如下圖所示
資料手冊要求,CLOCK之時脈必需介於10KHz~400KHz之間,配合上圖之動作要求,可先設計一簡單的讀取程式
;定義ADC0831接線位置 SCL EQU P1.3 SDA EQU P1.4 CS EQU P1.6 AD_BUF EQU 30H ;儲存AD轉換完成之資料 RD_AD0831: SETB SDA CLR CS MOV R7,#2 CALL DELAY1US SETB SCL MOV R7,#3 CALL DELAY1US CLR SCL MOV R7,#3 CALL DELAY1US MOV R4,#8 RD_AD: SETB SCL ;讀取8位元資料 MOV R7,#3 CALL DELAY1US CLR SCL MOV R7,#3 CALL DELAY1US MOV C,SDA RLC A DJNZ R4,RD_AD MOV R7,#3 CALL DELAY1US SETB CS MOV AD_BUF,A ;儲存轉換結果 RET DELAY1US: ;延遲時間 = R7 * 1 us(延遲時間以82G516為準) NOP NOP NOP NOP DJNZ R7,DELAY1US RET
讀取ADC0831的值並不難,再來要做的是如何處裡讀到的值,以下介紹2個將讀到的值顯示於LCD的方法
1.將8位元數值以10進制方式顯示於LCD
由於8位元數值範圍從0~255,轉換的結果最多有3位數,再此我們利用8051的除法指令 DIV AB ;A/B = A 餘 B 首先要轉換的數值存在A,將令B的數值為10,則透過DIV AB指令,此時計算結果之餘數為個位數值 例如 A = 156, B = 10, A/B = 15 餘 6 因為個位數要最後寫入LCD,所以先放在堆疊,把放在A的商在除以10,就可以把百位和十位分開 例如 A = 15, B = 10, A/B = 1 餘 5 0~9之ASCII碼為30H~39H,兩者相差30H,所以要將數值顯示於LCD前,需事先加上30H,以下為完整的轉換副程式
BIN_TO_DEC: MOV B,#10 DIV AB ;將累加器內容除10,累加器內容為商,包含十位和百位,餘數在B,為個位的值 PUSH B MOV B,#10 DIV AB ;累加器內容為百位,餘數在B,為十位的值 ADD A,#30H CALL WRDR ;將百位數顯示於LCD MOV A,B ADD A,#30H CALL WRDR ;將十位數顯示於LCD POP ACC ;將堆疊內的值取回存入累加器A ADD A,#30H CALL WRDR ;將個位數顯示於LCD RET
2.將8位元數值以16進制方式顯示於LCD
例如數值為 10011100, 則顯示9C
由於LCD要先從高位數先開始顯示,因此先處裡前四位元,處裡過程中會改變累加器後4位元的值,所以先透過PUSH ACC存到堆疊內, 再利用 SWAP A ;前後四位元資料交換 ANL A,#0FH ;前4位元清除為0 可求得此16進位數值,但0~9,A~F的ASCII碼分別為30H~39H,41H~46H,沒辦法仿照前述範例直接加上30H,此範例是利用查表的方式,建立字型表 FONT: DB '0123456789ABCDEF' 並將DPTR指到表的開頭(MOV DPTR,#FONT),再由MOVC A,@A+DPTR,利用A的值即可對應到該字的ASCII碼,以下為完整的轉換副程式 HEX_TO_ASCII: ;將16進制數值轉成ASCII碼顯示於LCD MOV DPTR,#FONT PUSH ACC ;暫時將累加器內的值儲存於堆疊 SWAP A ;前後四位元資料交換 ANL A,#0FH ;前4位元清除為0 MOVC A,@A+DPTR ;將數值轉成ASCII碼 CALL WRDR ;顯示於LCD POP ACC ANL A,#0FH MOVC A,@A+DPTR CALL WRDR RET FONT: DB '0123456789ABCDEF'
由於AD轉換的目的並不只是要顯示該數值,而是要將該數值所代表的的物理量(如電壓,重量,溫度...)計算出來,因此必須知道每變化一格所代表的數值意義,例如假設VCC電壓量到的值為4.34V,0~255數值轉換成0~4.34V,則每變化ㄧ格所代表的電壓為17 mV,如果要利用8051的組合語言計算,對組合語言不熟悉的使用者而言,有一定的困難度,建議利用C語言來寫會比較簡單,只要宣告好要計算的精確度(整數或長整數),寫好方程式,其他複雜的8051指令計算過程,就全交給編譯器去處裡。
電路板左上角之JP3提供3種訊號源選擇,實驗時若要使用實習板上之可變電阻,可將JP3最上面2隻接腳短路,再利用一字起子調整可變電阻,觀察LCD上之數值變化
2.82G516內建ADC之控制
ADCTL (Address=C5H, ADC Control Register, Reset Value=0000,0000B)
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADCON |
SPEED1 |
SPEED0 |
ADCI |
ADCS |
CHS2 |
CHS1 |
CHS0 |
ADCON: = 0, 關閉ADC電路, = 1 啟動ADC電路。 SPEED1,SPEED0: 類比到數位轉換速度選擇位元 (0,0): 轉換完成需 1080 個時脈週期。 (0,1): 轉換完成需 540 個時脈週期。 (1,0): 轉換完成需 360 個時脈週期。 (1,1): 轉換完成需 270 個時脈週期。 註:1個時脈週期所需時間為 1/Fosc.
ADCS: ADC啟動位元
設定此位元為1時,啟動A/D轉換,當轉換完成時,ADC硬體會自動清除ADCS,並將ADCI設為1。 ADCS不能由軟體清除。當ADCS或ADCI等於1時,無法啟動新的A/D轉換。.
ADCI: ADC 中斷旗號.
當A/D轉換完成時,此位元會被設值為1,如果中斷已經致能,將會產生中斷,此旗號須由軟體清除。This flag is set when an A/D conversion is completed. An interrupt is invoked if it is enabled. The flag should be cleared by software.
CHS2, CHS1 and CHS0: 輸入通道選擇位元。
(0,0,0): 選擇 AIN0 (P1.0) 做為類比輸入
(0,0,1): 選擇 AIN1 (P1.1) 做為類比輸入
(0,1,0): 選擇 AIN2 (P1.2) 做為類比輸入
(0,1,1): 選擇 AIN3 (P1.3) 做為類比輸入
(1,0,0): 選擇 AIN4 (P1.4) 做為類比輸入
(1,0,1): 選擇 AIN5 (P1.5) 做為類比輸入
(1,1,0): 選擇 AIN6 (P1.6) 做為類比輸入
(1,1,1): 選擇 AIN7 (P1.7) 做為類比輸入
AUXR (Address=8EH, Auxiliary Register, Reset Value=0000,xx0xB)
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
URTS |
ADRJ |
P41ALE |
P35ALE |
- |
- |
EXTRAM |
- |
ADRJ:
0: 轉換的結果前8位元儲存在 ADCH[7:0],後2位元儲存在
ADCL[1:0]。
1: 轉換的結果前2位元儲存在 ADCH[1:0],後8位元儲存在
ADCL[7:0]。
If ADRJ=0
ADCH (Address=C6H, ADC Result High-byte Register, Reset Value=xxH)
ADCL (Address=BEH, ADC Result Low-byte Register, Reset Value=xxH)
|
If ADRJ=1
ADCH (Address=C6H, ADC Result High-byte Register, Reset Value=xxH)
ADCL (Address=BEH, ADC Result Low-byte Register, Reset Value=xxH)
D |
;82G516內建AD測試程式, 轉換結果的高8位元顯示於P2 $INCLUDE (REG_MPC82G516.INC) START: MOV P1M0,#01000000B MOV P1M1,#00000000b ;設定 P1.6 為輸入 MOV ADCTL,#10000110B ;設定 P1.6 為A/D 輸入 AGAIN: ORL ADCTL,#00001000B ;啟動A/D轉換 (ADCS=1) wait: MOV A,ADCTL ;判斷是否轉換完成 JNB ACC.4,wait ANL ADCTL,#11101111B ;清除中斷轉換完成旗號 ADCI MOV P2,ADCH JMP AGAIN END