————————————————————————————————————————————
ADC0809
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
工作原理:
-
ADDA/ADDB/ADDC 輸入3 位地址,並使ALE=1,將地址存入地址鎖存器中
ALE:地址鎖存允許信號接入端,高電平時允許改變CBA的值,低電平時鎖死,防止在A/D轉換過程中切換通道
- 地址經譯碼選通8路模擬輸入IN0~IN7之一到比較器,輸入與被選通道關系
| 通道 |
C |
B |
A |
| IN0 |
0 |
0 |
0 |
| IN1 |
0 |
0 |
1 |
| IN2 |
0 |
1 |
0 |
| IN3 |
0 |
1 |
1 |
| IN4 |
1 |
0 |
0 |
| IN5 |
1 |
0 |
1 |
| IN6 |
1 |
1 |
0 |
| IN7 |
1 |
1 |
1 |
- START端上升沿將逐次逼近寄存器復位,下降沿啟動A/D轉換
- EOC輸出信號變低電平,表示正在轉換;當A/D轉換完成,EOC變為高電平,結果數據已存入鎖存器。
-
OE輸入高電平,輸出三態門打開,轉換結果的數字量輸出到數據總線上。
OE=1時,D0-D7引腳上為轉換后的數據,當OE=0時,D0-D7為對外呈現高阻狀態
p.s.
其他引腳:

IN0~IN7:8路模擬量輸入引腳
CLK:時鍾信號輸入端
V_(REF(+)):參考電壓正端
V_(REF(-)):參考電壓負端
————————————————————————————————————————————
數字電壓表實驗
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實現效果:
-
檢測外部模擬電壓,並用數字量將其電壓值表示出來

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實現思路:
-
A/D轉換
- 初始化時啟動A/D轉換,轉換結束后OE自動置位
- 檢查OE狀態,為高電平時讀取數據口數據並轉換成對應的電壓值
- 顯示結束后啟動下一次A/D轉換
-
數碼管顯示
- 讀入數據並轉換成電壓值后,通過數碼管顯示,百位數值后顯示小數點
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
連接說明:
| ADC0808 |
OUT1-OUT8 |
89C51 |
P0.0-0.7 |
轉換后數據輸出到單片機 |
|
|
START |
|
P3.0 |
|
|
|
EOC |
|
P3.1 |
|
|
|
OE |
|
P3.2 |
|
|
|
IN0 |
POT-HG |
+ |
輸入模擬信號 |
|
|
ADDA/ADDB/ADDC/VREF(-) |
GND |
|
0 0 0 選擇通路IN0 |
|
|
ALE/VREF(+) |
POWER |
|
將地址存入地址鎖存器中 |
| 數碼管 |
1/2/3/4/5/6/7 |
89C51 |
P2 |
控制數碼管顯示位數 |
|
|
A/B/C/D/E/F/G/DP |
|
P1 |
控制顯示段碼 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實現代碼:
1 #include <reg52.h> 2 typedef unsigned char uchar; 3 typedef unsigned int uint; 4 typedef unsigned long ulong; 5 uchar code table[] = 6 { 7 0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e 8 }; 9 sbit start = P3 ^ 0; //控制start引腳 10 sbit eoc = P3 ^ 1; //查詢eoc引腳情況 11 sbit oe = P3 ^ 2; //輸出允許控制端 12 sbit dot = P1 ^ 0; //數碼管小數點 13 void Delay(uint m) 14 { 15 while(m--); 16 } 17 void main() 18 { 19 ulong temp, temp_data; 20 // uint temp; 21 start = 0; 22 oe = 0; //oe為高阻狀態 23 start = 1; //start下降沿開始轉換 24 start = 0; 25 while(1) 26 { 27 if (eoc == 1) //當eoc為1時轉換結束 28 { 29 /*讀入狀態*/ 30 oe = 1; //打開oe,數據讀入引腳 31 temp = P0; 32 /* 33 讀入的數值轉換成模擬電壓對應的電壓值,由於ADC0809將0-5V平分為255份,每一份為5/255v,電壓=1.0v時,temp=1.0*(5/255),為了方便顯示小數,則擴大一百倍,得到公式temp=temp*1.0/255*500 34 但是在此處存在個問題,temp轉換成為flout類型后運算量過大,影響后數碼管顯示速度,在一定范圍內數碼管顯示錯誤 35 temp = temp * 1.0 / 255 * 500; → temp = temp * 500 / 255; 36 p.s. 修改后的temp要改成unsigned long, FF*500溢出int范圍 37 */ 38 temp = temp * 500 / 255; 39 oe = 0; //oe呈高阻 40 /*數碼管顯示*/ 41 temp_data = temp % 10; 42 P2 = 0xfe; //數碼管選擇最后一位 43 P1 = table[temp_data]; 44 Delay(500); 45 temp_data = temp / 10 % 10; 46 P2 = 0xfd; //數碼管選擇十位 47 P1 = table[temp_data]; 48 Delay(500); 49 temp_data = temp / 100 % 10; 50 P2 = 0xfb; //數碼管選擇百位 51 P1 = table[temp_data]; 52 dot = 1; //顯示小數點 53 Delay(500); 54 /*啟動下一次轉換*/ 55 start = 1; 56 start = 0; 57 } 58 } 59 }

