模擬信號(hào)只有通過A/D轉(zhuǎn)化為數(shù)字信號(hào)后才能用軟件進(jìn)行處理,這一切都是通過A/D轉(zhuǎn)換器(ADC)來實(shí)現(xiàn)的。與模數(shù)轉(zhuǎn)換相對(duì)應(yīng)的是數(shù)模轉(zhuǎn)換,數(shù)模轉(zhuǎn)換是模數(shù)轉(zhuǎn)換的逆過程,在一般的工業(yè)應(yīng)用系統(tǒng)中傳感器把非電量的模擬信號(hào)變成與之對(duì)應(yīng)的模擬信號(hào),然后經(jīng)模擬(Analog)到數(shù)字(Digital)轉(zhuǎn)換電路將模擬信號(hào)轉(zhuǎn)成對(duì)應(yīng)的數(shù)字信號(hào)送微機(jī)處理。這就是一個(gè)完整的信號(hào)鏈,模擬到數(shù)字的轉(zhuǎn)換過程就是我們經(jīng)常接觸到的ADC電路。
模數(shù)轉(zhuǎn)換原理:
ADC的轉(zhuǎn)換原理根據(jù)ADC的電路形式有所不同。 ADC電路通常由兩部分組成,它們是:采樣、保持電路和量化、編碼電路。其中量化、編碼電路是最核心的部件,任何ADC轉(zhuǎn)換電路都必須包含這種電路。 ADC電路的形式很多,通常可以并為兩類:
間接法:它是將采樣-保持的模擬信號(hào)先轉(zhuǎn)換成與模擬量成正比的時(shí)間或頻率,然后再把它轉(zhuǎn)換為數(shù)字量。這種通常是采用時(shí)鐘脈沖計(jì)數(shù)器,它又被稱為計(jì)數(shù)器式。它的工作特點(diǎn)是:工作速度低,轉(zhuǎn)換精度高,抗干擾能力強(qiáng)。
直接法:通過基準(zhǔn)電壓與采樣-保持信號(hào)進(jìn)行比較,從而轉(zhuǎn)換為數(shù)字量。它的工作特點(diǎn)是:工作速度高,轉(zhuǎn)換精度容易保證。
模數(shù)轉(zhuǎn)換的過程:
有四個(gè)階段,即采樣、保持、量化和編碼。
采樣是將連續(xù)時(shí)間信號(hào)變成離散時(shí)間信號(hào)的過程。經(jīng)過采樣,時(shí)間連續(xù)、數(shù)值連續(xù)的模擬信號(hào)就變成了時(shí)間離散、數(shù)值連續(xù)的信號(hào),稱為采樣信號(hào)。采樣電路相當(dāng)于一個(gè)模擬開關(guān),模擬開關(guān)周期性地工作。理論上,每個(gè)周期內(nèi),模擬開關(guān)的閉合時(shí)間趨近于0。在模擬開關(guān)閉合的時(shí)刻(采樣時(shí)刻),我們就“采”到模擬信號(hào)的一個(gè)“樣本”。
量化是將連續(xù)數(shù)值信號(hào)變成離散數(shù)值信號(hào)的過程。理論上,經(jīng)過量化,我們就可以將時(shí)間離散、數(shù)值連續(xù)的采樣信號(hào)變成時(shí)間離散、數(shù)值離散的數(shù)字信號(hào)。
我們知道,在電路中,數(shù)字量通常用二進(jìn)制代碼表示。因此,量化電路的后面有一個(gè)編碼電路,將數(shù)字信號(hào)的數(shù)值轉(zhuǎn)換成二進(jìn)制代碼。
然而,量化和編碼總是需要一定時(shí)間才能完成,所以,量化電路的前面還要有一個(gè)保持電路。保持是將時(shí)間離散、數(shù)值連續(xù)的信號(hào)變成時(shí)間連續(xù)、數(shù)值離散信號(hào)的過程。在量化和編碼期間,保持電路相當(dāng)于一個(gè)恒壓源,它將采樣時(shí)刻的信號(hào)電壓“保持”在量化器的輸入端。雖然邏輯上保持器是一個(gè)獨(dú)立的單元,但是,工程上保持器總是與采樣器做在一起。兩者合稱采樣保持器。
八位串行A/D轉(zhuǎn)換器ADC0832簡(jiǎn)介:
ADC0832 是美國(guó)國(guó)家半導(dǎo)體公司生產(chǎn)的一種8 位分辨率、雙通道A/D轉(zhuǎn)換芯片。由于它體積小,兼容性強(qiáng),性價(jià)比高而深受單片機(jī)愛好者及企業(yè)歡迎,其目前已經(jīng)有很高的普及率。ADC083X是市面上常見的串行模—數(shù)轉(zhuǎn)換器件系列。ADC0831、ADC0832、ADC0834、ADC0838是具有多路轉(zhuǎn)換開關(guān)的8位串行I/O模—數(shù)轉(zhuǎn)換器,轉(zhuǎn)換速度較高(轉(zhuǎn)換時(shí)間32uS),單電源供電,功耗低(15mW),適用于各種便攜式智能儀表。本章以ADC0832為例,介紹其使用方法。
ADC0832是8腳雙列直插式雙通道A/D轉(zhuǎn)換器,能分別對(duì)兩路模擬信號(hào)實(shí)現(xiàn)模—數(shù)轉(zhuǎn)換,可以用在單端輸入方式和差分方式下工作。ADC0832采用串行通信方式,通過DI 數(shù)據(jù)輸入端進(jìn)行通道選擇、數(shù)據(jù)采集及數(shù)據(jù)傳送。8位的分辨率(較高分辨可達(dá)256級(jí)),可以適應(yīng)一般的模擬量轉(zhuǎn)換要求。其內(nèi)部電源輸入與參考電壓的復(fù)用,使得芯片的模擬電壓輸入在0~5V之間。具有雙數(shù)據(jù)輸出可作為數(shù)據(jù)校驗(yàn),以減少數(shù)據(jù)誤差,轉(zhuǎn)換速度快且穩(wěn)定性能強(qiáng)。獨(dú)立的芯片使能輸入,使多器件掛接和處理器控制變的更加方便。
ADC0832特點(diǎn):
· 8位分辨率;
· 雙通道A/D轉(zhuǎn)換;
· 輸入輸出電平與TTL/CMOS相兼容;
· 5V電源供電時(shí)輸入電壓在0~5V之間;
· 工作頻率為250KHZ,轉(zhuǎn)換時(shí)間為32μS;
· 一般功耗僅為15mW;
· 8P、14P—DIP(雙列直插)、PICC 多種封裝;
· 商用級(jí)芯片溫寬為0°C to +70°C,工業(yè)級(jí)芯片溫寬為-40°C to +85°C;
ADC0832引腳圖
芯片接口說明:
· CS_ 片選使能,低電平芯片使能。
· CH0 模擬輸入通道0,或作為IN+/-使用。
· CH1 模擬輸入通道1,或作為IN+/-使用。
· GND 芯片參考零電位(地)。
· DI 數(shù)據(jù)信號(hào)輸入,選擇通道控制。
· DO 數(shù)據(jù)信號(hào)輸出,轉(zhuǎn)換數(shù)據(jù)輸出。
· CLK 芯片時(shí)鐘輸入。
· Vcc/REF 電源輸入及參考電壓輸入(復(fù)用)
ADC0832的工作原理:
正常情況下ADC0832 與單片機(jī)的接口應(yīng)為4條數(shù)據(jù)線,分別是CS、CLK、DO、DI。但由于DO端與DI端在通信時(shí)并未同時(shí)使用并與單片機(jī)的接口是雙向的,所以在I/O口資源緊張時(shí)可以將DO和DI并聯(lián)在一根數(shù)據(jù)線上使用。當(dāng)ADC0832未工作時(shí)其CS輸入端應(yīng)為高電平,此時(shí)芯片禁用,CLK 和DO/DI 的電平可任意。當(dāng)要進(jìn)行A/D轉(zhuǎn)換時(shí),須先將CS使能端置于低電平并且保持低電平直到轉(zhuǎn)換完全結(jié)束。此時(shí)芯片開始轉(zhuǎn)換工作,同時(shí)由處理器向芯片時(shí)鐘(CLK)輸入端輸入時(shí)鐘脈沖,DO/DI端則使用DI端輸入通道功能選擇的數(shù)據(jù)信號(hào)。在一個(gè)時(shí)鐘脈沖的下沉之前DI端必須是高電平,表示啟始信號(hào)。在第二、三個(gè)脈沖下沉之前DI端應(yīng)輸入兩位數(shù)據(jù)用于選擇通道功能。
表1:通道地址設(shè)置表
如表1所示,當(dāng)此兩位數(shù)據(jù)為“1”、“0”時(shí),只對(duì)CH0 進(jìn)行單通道轉(zhuǎn)換。當(dāng)2位數(shù)據(jù)為“1”、“1”時(shí),只對(duì)CH1進(jìn)行單通道轉(zhuǎn)換。當(dāng)兩位數(shù)據(jù)為“0”、“0”時(shí),將CH0作為正輸入端IN+,CH1作為負(fù)輸入端IN-進(jìn)行輸入。當(dāng)兩位數(shù)據(jù)為“0”、“1”時(shí),將CH0作為負(fù)輸入端IN-,CH1 作為正輸入端IN+進(jìn)行輸入。到第三個(gè)脈沖的下降之后DI端的輸入電平就失去輸入作用,此后DO/DI端則開始利用數(shù)據(jù)輸出DO進(jìn)行轉(zhuǎn)換數(shù)據(jù)的讀取。從第4個(gè)脈沖下降沿開始由DO端輸出轉(zhuǎn)換數(shù)據(jù)最高位Data7,隨后每一個(gè)脈沖的下降沿DO端輸出下一位數(shù)據(jù)。直到第11個(gè)脈沖時(shí)發(fā)出最低位數(shù)據(jù)Data0,一個(gè)字節(jié)的數(shù)據(jù)輸出完成。也正是從此位開始輸出下一個(gè)相反字節(jié)的數(shù)據(jù),即從第11個(gè)字節(jié)的下降沿輸出Data0。隨后輸出8位數(shù)據(jù),到第19 個(gè)脈沖時(shí)數(shù)據(jù)輸出完成,也標(biāo)志著一次A/D轉(zhuǎn)換的結(jié)束。最后將CS置高電平禁用芯片,直接將轉(zhuǎn)換后的數(shù)據(jù)進(jìn)行處理就可以了。時(shí)序說明請(qǐng)參照?qǐng)D4。
作為單通道模擬信號(hào)輸入時(shí)ADC0832的輸入電壓是0—5V且8位分辨率時(shí)的電壓精度為19.53mV,即(5/256)V。如果作為由IN+與IN-輸入的輸入時(shí),可是將電壓值設(shè)定在某一個(gè)較大范圍之內(nèi),從而提高轉(zhuǎn)換的寬度。但值得注意的是,在進(jìn)行IN+與IN-的輸入時(shí),如果IN-的電壓大于IN+的電壓則轉(zhuǎn)換后的數(shù)據(jù)結(jié)果始終為00H。
ADC0832的工作時(shí)序
ADC0832軟硬件設(shè)計(jì)實(shí)例
通過以上的理論學(xué)習(xí)之后,對(duì)模—數(shù)轉(zhuǎn)換應(yīng)該有了一定的了解,接下來就根據(jù)上文的指導(dǎo),對(duì)ADC0832進(jìn)行實(shí)際應(yīng)用,以加深印象。本實(shí)例功能是將通道1上采樣到的電壓顯示在LED數(shù)碼管上,通過改變通道1的輸入電壓變化,觀察輸出讀數(shù)。
硬件原理圖
軟件流程圖
STC單片機(jī)的相關(guān)程序:
#include //定義的 系統(tǒng)頭文件和全局變量
#include
#define uchar unsigned char
#define uint unsigned int
#define DogReset() WDT_CONTR=0x35
// T1 定時(shí) 0.1ms.作為系統(tǒng)計(jì)時(shí)用,
#define vT01ms 2
#define vT10ms 10
#define vT100ms 10
#define vT01S 100 // 1 s = 10 ms * 100
#define vT0HVal 0xfe //0xff //0xfe //0xf6
#define vT0LVal 0x33 //0x9c //0x0c //0x4c
uchar code display_AD_channel_ID[2] = {0x00,0x01};
static unsigned char data CS;
uchar data AD_channel_result[2][5]; //各通道A/D轉(zhuǎn)換結(jié)果。前是通道號(hào);后是轉(zhuǎn)換的值
uint cT01ms;
uchar cT10ms;
uchar cT100ms;
uchar cT01s;
uchar THTL;
bit OutFlag;
void delay_ms(register uint Count){
register uchar T;
for(;Count》0;Count--){
for(T=0;T《80;T++){
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
DogReset();
}
}
void send_char_com(unsigned char OutData){
SBUF = OutData; //輸出字符
while(!TI); //空語句判斷字符是否發(fā)完
TI = 0; //清TI
}
void send_string_com(uchar *str,uchar strlen){
uchar i;
for(i=strlen; i》0; i--){
send_char_com(*str);
str++;
DogReset();
}
}
uchar Ad_Change(uchar channel){
uint AD_Result_Temp = 0 ;
//---------------------將P1.0--P1.1設(shè)置成適合AD轉(zhuǎn)換的模式
/// P1 = 0xff; //將P1口置高,為A/D轉(zhuǎn)換作準(zhǔn)備
ADC_CONTR = ADC_CONTR|0x80; //1000,0000打開A/D轉(zhuǎn)換電源
P1M0 = 0x03; //0000,0011用于A/D轉(zhuǎn)換的P1.x口,先設(shè)為開漏
P1M1 = 0x03; //0000,0011P1.0--P1.1先設(shè)為開漏。斷開內(nèi)部上拉電阻
delay_ms(20); //20
ADC_CONTR = ADC_CONTR&0xE0; //1110,0000 清ADC_FLAG,ADC_START位和低3位
ADC_CONTR = ADC_CONTR|(display_AD_channel_ID[channel]&0x07); //設(shè)置當(dāng)前通道號(hào)
delay_ms(1); //延時(shí)使輸入電壓達(dá)到穩(wěn)定
ADC_DATA = 0; //清A/D轉(zhuǎn)換結(jié)果寄存器
ADC_LOW2 = 0;
ADC_CONTR = ADC_CONTR|0x08; //0000,1000ADCS = 1,啟動(dòng)轉(zhuǎn)換
do { DogReset();}
while((ADC_CONTR & 0x10)==0); //0001,0000等待A/D轉(zhuǎn)換結(jié)束
ADC_CONTR = ADC_CONTR&0xE7; //1110,0111清ADC_FLAG位,停止A/D轉(zhuǎn)換
AD_Result_Temp = ((AD_Result_Temp|ADC_DATA)《《2)|(ADC_LOW2&0x03);
//保存返回AD轉(zhuǎn)換的 結(jié)果
//----------------------------轉(zhuǎn)換成可由串口顯示的字符
AD_channel_result[channel][0] = AD_Result_Temp/1000+0x30;
AD_channel_result[channel][1] = (AD_Result_Temp%1000)/100+0x30;
AD_channel_result[channel][2] = (AD_Result_Temp%100)/10+0x30;
AD_channel_result[channel][3] = AD_Result_Temp%10+0x30;
//------------------------串口監(jiān)視
// send_char_com(ADC_DATA); //////發(fā)送轉(zhuǎn)換 的 到的 值,這里只是 高8位,值的轉(zhuǎn)換需要考慮
// send_char_com(ADC_LOW2); //////發(fā)送轉(zhuǎn)換 的 到的 值,這里只是 低2位,值的轉(zhuǎn)換需要考慮
// send_string_com(AD_channel_result[channel],4);
delay_ms(10); //
return(ADC_DATA);
}
uchar AD_Filter(void){
uchar i;
uchar cTemp[32];
uchar cAverage;
for(i=32;i》0;i--){
cTemp[i]=Ad_Change(0);
cAverage=((cAverage+cTemp[i])》》1);
}
return(cAverage);
}
void InitCom(unsigned char BaudRate){
switch (BaudRate){
case 1: THTL = 64; break; //波特率300
case 2: THTL = 160; break; //600
case 3: THTL = 208; break; //1200
case 4: THTL = 232; break; //2400
case 5: THTL = 244; break; //4800
case 6: THTL = 250; break; //9600
case 7: THTL = 253; break; //19200
case 8: THTL = 255; break; //57600
default: THTL = 208; break; //1200
}
}
void Chip_initial(void){
IE=0;
// 定時(shí)器控制字初始化
TMOD=0x21; // 定時(shí)器1為方式2,定時(shí)器0為方式1
TCON=0x50; // 設(shè)置外部中斷類型
T2CON=0x0d; // 選擇定時(shí)器1為波特率發(fā)生器,T2為捕獲工作方式
// ET2=1;
ET0=1; // 允許定時(shí)器0、定時(shí)器2中斷
// 外部中斷設(shè)置
EX0=0; // FFSK中斷初始時(shí)關(guān)閉,有載波時(shí)再開啟
EX1=0;
IT1=1; // 外部中斷0、1均為下降沿觸發(fā)
IT0=1;
// 啟動(dòng)定時(shí)器0
TH0=vT0HVal; // 啟動(dòng)定時(shí)器0
TL0=vT0LVal;
TR0=1;
InitCom(6); //設(shè)置波特率為9600 1-7波特率300-19200
SCON = 0x50; //串口方式1,允許接收
TH1 = THTL;
TL1 = THTL;
PCON = 0x80; //波特率加倍控制,SMOD位
RI = 0; //清收發(fā)標(biāo)志
TI = 0;
TR1 = 1; //啟動(dòng)定時(shí)器
IP=0x02; //PT2=1
IPH=0x02; //PT2H=1,PT0H=1
EA=1;
delay_ms(10); // 延時(shí)是為了避免定時(shí)器0無法產(chǎn)生中斷的問題
}
void Para_initial(void){
OutFlag=0;
cT01ms = vT01ms;
cT10ms = vT10ms;
// cT100ms = vT100ms;
cT01s = vT01S;
CS = 0; //設(shè)置CS為0不選任何的音源,如為1則選第1路
}
void system_initial(void){
Chip_initial();
Para_initial();
DogReset(); // 已針對(duì) STC89C58RD+ 作修改.06-04-06
}
void main(void){
system_initial();
while(1){
DogReset();
if(OutFlag){
OutFlag=0;
send_char_com(AD_Filter());
}
}
}
void Trint0(void) interrupt 1 using 1{
TR0=0; // 時(shí)基1mS
TH0=vT0HVal;
TL0=vT0LVal;
TR0=1;
TF0=0;
if(!(--cT01ms)){
cT01ms=vT01ms;
if(!(--cT10ms)){
cT10ms=vT10ms;
if(!(--cT01s)){
cT01s=vT01S;
OutFlag=1;
}
}
}
}
void ComInINT(void) interrupt 4 {
if (RI){ //判斷是不收完字符
switch(SBUF){
case 0x61: CS = 1; break; //根據(jù)SBUF設(shè)置CS 接收‘a(chǎn)bcde’調(diào)試方便
case 0x62: CS = 2; break;
case 0x63: CS = 3; break;
case 0x64: CS = 4; break;
case 0x65: CS = 0; break;
}
P1 = 255; //P1口全為高電平,4-7通過反相為低不選任何音源,0-3為高用于讀取按鍵
RI = 0; //RI清零
}
}
小編推薦閱讀:
adc0832是什么_adc0832和adc0809區(qū)別
評(píng)論
查看更多