基於0808模/數轉換器的電壓測試仿真

前言:使用A/D轉換器模擬電壓表功能


1. 基礎


(1)模/數(A/D)轉換器

    轉換的功能是把模擬量電壓轉換爲N位數字量電壓。A/D轉換器主要性能指標有分辨率、誤差、轉換精度、轉換速度等。

    按轉換原理分類,有逐次逼近式、雙積分式、並行式等。雙積分轉換精度高,轉換時間長,大約需要幾百毫秒;並行式轉換速度最高,能達到2G次,即轉換時間僅50ns,但價格昂貴,產品的分辨率不高;逐次逼近式兼顧了轉換速度和轉換精度,是應用廣泛的A/D轉換器。

    逐次逼近式的各類很多,分辨率從8位到16位,轉換時間從100μs到幾微秒,精度有不同等級。常用的幾種A/D轉換器:8位通用型ADC0808/0809、12位的AD574A和雙積分型5G14433。

(2)ADC0808/0809的主要性能指標

    分辨率爲8位;總的非調整誤差:0808爲±  LSB,0809爲±1 LSB;具有鎖存控制功能的8路模擬開關,能對8路模擬電壓信號進行轉換;輸出電平與TTL電平兼容;單電源+5V供電;工作時序,完成一次轉換所需要的時候爲66~73個時鐘週期;


    轉換結束信號的處理方式。當A/D轉換結束,ADC輸出一個轉換結束信號,通知主要A/D轉換已經結束,可以讀取結果,可以讀取結果。主機檢查判斷A/D轉換是否結束的方法主要有四種:中斷方式、查詢方式、延時方式、DMA方式。

2. 仿真電路設計


(1)元件:

    單片機(AT89C51)、4位共陰極數碼管(7SEG-MPX4-CC-BLUE)、ADC0808、變阻器、電壓表。

(2)內容:

    對於數碼管,P1段控,P2位控;P3控制ADC;P0接收ADC轉換結果;變阻器控制ADC輸入模擬電壓值;示波器與計數器監控P3^3輸出方波/時鐘。

(3)電路連線:


3. 程序設計


(1)內容:

    以查詢方式監控EOC;將ADC結果換算成電壓值,並循環顯示轉換結果;使用T1定時器控制P3^3輸出方波頻率(用於ADC輸入時鐘),輸入方波週期爲20μs(即T1以10μs轉換電平),即10^6/20μs=50kHz;用for/delay控制數碼管顯示延時。

(2)代碼:

#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
 
// ADC控制
sbit START =  P3^0;
sbit OE = P3^1;
sbit EOC = P3^2;
sbit CLK = P3^3;
 
// ADC輸入-地址碼
sbit P34 = P3^4;
sbit P35 = P3^5;
sbit P36 = P3^6;
 
// 控制小數點段碼位
sbit P17 = P1^7;
 
 
void Delay(uint);
void LedScan(uint);
void T1_Init(void);
 
// common cathode(共陰極)
// Led code, "0~9, A~F"
uchar LedOfNum[] =
{
       0x3f, 0x06, 0x5b, 0x4f,0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
       0x77, 0x7c, 0x39, 0x5e,0x79, 0x71
};
uchar ADC_data;
uint temp;
 
 
/******************** Main function ********************/
void main(void)
{
       T1_Init();
       while (1)
       {
              START = 0;
              OE = 0;
              START = 1;
              START = 0;
              P34 = 0;
              P35 = 0;
              P36 = 0;
              do
              {}while(!EOC);  // 查詢方式,確認EOC的狀態
              OE = 1;  // ADC輸出使能
              ADC_data = P0;  // 獲得ADC結果
              OE = 0;  // ADC關輸出使能
              temp = ADC_data *1.0 / 255 * 500;  // 將數字結果換算成模擬量
              LedScan(temp);
       }
}
 
/******************** Led scan ********************/
// P1控制段碼顯示
// P2位控(共陰極)
void LedScan(uint num)
{
       uchar g, s, b, q;
       uchar k;
       g = num%10;
       s = num/10%10;
       b = num/100%10;
       q = num/1000;
       for (k=0; k<150; k++)
       {
              P1 = LedOfNum[q];
              P2 = 0x0E;     // 0000 1110B
              Delay(1);
              P1 = 0x00;     // 0000 0000B
 
              P1 = LedOfNum[b];
              P17 = 1;
              P2 = 0x0D;     // 0000 1101B
              Delay(1);
              P1 = 0x00;     // 0000 0000B
 
              P1 = LedOfNum[s];
              P2 = 0x0B;     // 0000 1011B
              Delay(1);
              P1 = 0x00;     // 0000 0000B
 
              P1 = LedOfNum[g];
              P2 = 0x07;     // 0000 0111B
              Delay(1);
              P1 = 0x00;     // 0000 0000B
       }
}
 
 
/******************** Delay function ********************/
void Delay(uint x)
{
       uchar k;
       while (x--)
              for(k=0;k<125; k++) ;
}
 
/******************** T1_Init function ********************/
void T1_Init(void)
{
       TMOD = 0X10;
       TH1 = (65536-10) / 256;
       TL1 = (65536-10) % 256;
       EA = 1;          // 開中斷
       ET1 = 1; // 允許T1中斷
       TR1 = 1; // 啓動T1
}
 
 
/******************** T1_Init function ********************/
void T1_Timer(void) interrupt 3
{
       TH1 = (65536-10) / 256;  // 相當於半週期爲10us,全週期爲20us的方波;即10^6/20us=50kHz
       TL1 = (65536-10) % 256;
       CLK = ~CLK;
}

4. 仿真操作


(1)裝入HEX文件,運行。

(2)運行結果:

    a. ADC轉換結果與電壓表相當,存在轉換誤差


    b. 計數器監控P3^3輸出方波頻率;因設置下降沿有效,所以頻率少一半;又for/delay佔用CPU時間,頻率誤差加大。


    c. 示波器監控P3^3;因設置上升沿有效,所以週期長一倍;週期接近40μs。



5. 實物確認

    還是用以上程序,實物連線確認,實際電壓和轉換結果還是有差異,就如Proteus裏仿真一般。這個問題還得繼續摸索。




下一步:

    for/delay改T0定時器以減少對CPU佔用;實物電路做成,以確認實際運行結果、以及ADC0808輸入時鐘真實要求。


參考:《單片機C語言與Proteus仿真技能實訓》、《Proteus入門實用教程》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章