關於AD轉換的原理,大家在《數字電子技術》中已經學過,這裡做過多的介紹,本文介紹一款經典的8位AD轉換晶片ADC0804,基於51單片機設計AD轉換電路,並完成測量值的轉換。
CS:片選信號,低電平有效,即CS=0時候晶片才能正常工作,單獨一個ADC0804晶片時候直接置零。當有多個晶片時候可以通過片選信號實現分時復用。
WR:低電平有效,當WR信號由高到低時候實現一次ADC轉換。
RD:低電平有效,RD=0時候可以讀取數據。
Vin+:模擬電壓輸入端。
Vin-:一般接地,當模擬電壓是雙邊輸入時候Vin+和Vin-分別接模擬電壓的正負極。
VREF/2:參考電壓接入引腳,可懸空或接外界電壓。接外電壓時候晶片的參考電壓為所接電壓的兩倍。懸空時候晶片參考電壓為VCC。
CLKR/CLKIN:外接RC電路產生轉換所需的時鐘信號,CLK=1/1.1RC。
AGND和DGND:模擬和數字地。
INTR:中斷請求信號輸出引腳,當完成一次AD轉換後該引腳為低電平,一般與單片機的中斷信號相連。
DB0~DB7:輸出轉換後的八位二進位結果。
Proteus仿真電路:
啟動轉換時序
先將CS置低電平,晶片開始工作,WR隨後置低,經過一段時間的低電平之後,WR拉高,AD轉換啟動,經過1-8個A/D時鐘周期後,模數轉換完成,INTR引腳拉低,通知單片機本次轉換完成。
數據讀取時序
當INTR為低電平時,先將CS置低,接著RD置低,經過一段時間後數字輸出口上的數據達到穩態,此時單片機可以讀取數據,讀取完成後將RD拉高,最後將CS拉高。INTR自動變化,無需人為操作。一般在只有一片ADC0804晶片時候,可以一直將CS置低。
51單片機讀取ADC0804數據的方式有兩種,一種是通過不斷掃描的方式讀取;另一種是將ADC0804的INTR引腳接單片機的中斷引腳,當AD轉換完成後,通過外部中斷的方式通知單片機讀取數據。
Proteus仿真電路圖
原始碼:
include <intrins.h>sbit CS=P3^5;sbit adrd=P3^7;sbit adwr=P3^6;unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};unsigned char com[]={0x01,0x02,0x04,0x08};unsigned char num,num2=0,time[4]={0,0,0,0},val;float val2;unsigned int val3;void main(){TMOD=0x01;TH0=(65536-917)/256;TL0=(65536-917)%256;;EA=1;ET0=1;TR0=1;CS=0;while(1){adwr = 1;//_nop_();adwr = 0;//_nop_();adwr = 1;//P1 = 0xff;//adrd = 1;//_nop_();adrd = 0;//_nop_();val = P1;//adrd = 1;//val2=((val*1.0/255)*5.0);val3=val2*1000;time[0]=val3/1000;time[1]=val3%1000/100;time[2]=val3%100/10;time[3]=val3%10;}}void Timer0() interrupt 1{TH0 = (65536-917)/256;TL0 = (65536-917)%256;;num++;if(num==10){num=0;P0=~com[num2];P2=0xff;if(num2==0){P2=display[time[num2]]|0x80;}else{P2=display[time[num2]];}num2++;if(num2>=4)num2=0;}}
Proteus仿真電路
原始碼:
include <intrins.h>sbit CS=P3^5;sbit adrd=P3^7;sbit adwr=P3^6;unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};unsigned char com[]={0x01,0x02,0x04,0x08};unsigned char num,num2=0,time[4]={0,0,0,0},val;float val2;unsigned int val3;void Delay50ms() //@11.0592MHz{unsigned char i, j, k;_nop_();_nop_();i = 3;j = 26;k = 223;do{do{while (--k);} while (--j);} while (--i);}void main(){TMOD=0x01;TH0=(65536-917)/256;TL0=(65536-917)%256;;EA=1;ET0=1;TR0=1;EX0=1;IT0 = 0;CS=0;while(1){adwr = 1;//_nop_();adwr = 0;//_nop_();adwr = 1;//Delay50ms();}}void Timer0() interrupt 1{TH0 = (65536-917)/256;TL0 = (65536-917)%256;;num++;if(num==10){num=0;P0=~com[num2];P2=0xff;if(num2==0){P2=display[time[num2]]|0x80;}else{P2=display[time[num2]];}num2++;if(num2>=4)num2=0;}}void Init0() interrupt 0{adrd = 1;//_nop_();adrd = 0;//_nop_();val = P1;//adrd = 1;//val2=((val*1.0/255)*5.0);val3=val2*1000;time[0]=val3/1000;time[1]=val3%1000/100;time[2]=val3%100/10;time[3]=val3%10;}