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指令計算過程,就全交給編譯器去處裡。

範例(ASM)

範例(C)

電路板左上角之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)

7

6

5

4

3

2

1

0

(B9)

(B8)

(B7)

(B6)

(B5)

(B4)

(B3)

(B2)

ADCL (Address=BEH, ADC Result Low-byte Register, Reset Value=xxH)

7

6

5

4

3

2

1

0

-

-

-

-

-

-

(B1)

(B0)

If ADRJ=1

ADCH (Address=C6H, ADC Result High-byte Register, Reset Value=xxH)

7

6

5

4

3

2

1

0

-

-

-

-

-

-

(B9)

(B8)

ADCL (Address=BEH, ADC Result Low-byte Register, Reset Value=xxH)

7

6

5

4

3

2

1

0

(B7)

(B6)

(B5)

(B4)

(B3)

(B2)

(B1)

(B0)

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

範例下載

 

範例(C語言)