本帖最后由 ziba108 于 2018-6-8 22:02 編輯
ADC0809模數轉換程序及詳解
對于初學者通過51單片機在加ADC0809模數轉換尤其很重要,很多傳感器得來的數據必須轉換后
進一步通過51單片機來送到下一個環節,所以跟深層的了解模數轉換很有必要。
模數轉換器最重要的參數是轉換的精度,通常用輸出的數字信號的位數的多少表示。轉換器能夠準確輸出的數字信號的位數越多,表示轉換器能夠分辨輸入信號的能力越強,轉換器的性能也就越好。 A/D 轉換一般要經過采樣、保持、量化及編有些過程是合并進碼4 個過程。在實際電路中,如采樣和保持,量化和編碼在轉換過程中行的,是同時實現的。 而ADC0809是采樣頻率為8位的、以逐次逼近原理進行模—數轉換的器件。其內部有一個8通道多路開關,它可以根據地址碼鎖存譯碼后的信號,只選通8路模擬輸入信號中的一個進行A/D轉換。 ADC0809主要特性: 1)8路8位A/D轉換器,即分辨率8位。 2)具有轉換起停控制端。 3)轉換時間為100μs 4)單個+5V電源供電 5)模擬輸入電壓范圍0~+5V,不需零點和滿刻度校準。 6)工作溫度范圍為-40~+85攝氏度 7)低功耗,約15mW。 ADC0809內部結構 ADC0809外部特性(引腳功能) ADC0809芯片有28條引腳,采用雙列直插式封裝,下面說明各引腳功能。 IN0~IN7:8路模擬量輸入端。 2-1~2-8:8位數字量輸出端。 ADDA、ADDB、ADDC:3位地址輸入線,用于選通8路模擬輸入中的一路 ALE:地址鎖存允許信號,輸入,高電平有效。 START: A/D轉換啟動信號,輸入,高電平有效。 EOC: A/D轉換結束信號,輸出,當A/D轉換結束時,此端輸出一個高電平(轉換期間一直為低電平)。 OE:數據輸出允許信號,輸入,高電平有效。當A/D轉換結束時,此端輸入一個高電平,才能打開輸出三態門,輸出數字量。 CLK:時鐘脈沖輸入端。要求時鐘頻率不高于640KHZ。 REF(+)、REF(-):基準電壓。 Vcc:電源,單一+5V。 GND:地。
ADC0809的工作過程是:首先輸入3位地址,并使ALE=1,將地址存入地址鎖存器中。此 地址經譯碼選通8路模擬輸入之一到比較器。START上升沿將逐次逼近寄存器復位。下降沿啟動 A/D轉換,之后EOC輸出信號變低,指示轉換正在進行。直到A/D轉換完成,EOC變為高電平,指示A/D轉換結束,結果數據已存入鎖存器,這個信號可 用作中斷申請。當OE輸入高電平 時,輸出三態門打開,轉換結果的數字量輸出到數據總線上。
值得一提的是,我按照上面電路,把AD的ABC三腳共同接接地時,AD0809088始終輸出高電平,最后當我把BC共同接地,在程序中給A一個0,則AD0809正常運行,有輸出,并且發現當所給的時鐘頻率越低,最高精度的那位輸出越穩定。 ADC0809模數轉換完整的程序: #include《 reg52.h》 #define uint unsigned int #define uchar unsigned char uchar aa,qian,bai,shi,ge; uint temp; sbit clock=P2^0; sbit start=P2^1; sbit eoc=P2^2; sbit oe=P2^3; sbit ale=P2^4; sbit adda=P2^5; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; //void display(uchar bai,uchar shi,uchar ge); void delay(uint z); void main() { TMOD=0x20; //設置定時器1為工作方式2 TH1=0x216; //216 TL1=0x216; //216 EA=1; //開總中斷 ET1=1; //開t1中斷 TR1=1; start=0; //復位 oe=0; //輸出 adda=0; //eoc=0; ale=0; //關閉地址選擇 while(1) { start=0; ///delay(10); start=1; // 復位 ale=1; // 打開地址選擇 adda=0; ///delay(10); start=0; // 開始轉換 ale=0; // 關地址 //delay(1); while(eoc==0); // 等待eoc變為1 //delay(1); oe=1; // 打開輸出 //delay(1); //P1=0xff; temp=P1; // 取p1到p3 oe=0; // 關輸出 temp=temp*50; temp=temp/256; qian=temp/1000; bai=temp%1000/100; shi=temp%100/10; ge=temp%10; P3=0x00; P0=0xfe; P3=table[qian]; delay(50); P3=0x00; P0=0xfd; P3=table[bai]; delay(50); P3=0x00; P0=0xfb; P3=table[shi]; delay(50); P3=0x00; P0=0xf7; P3=table[ge]; } } void delay(uint z) { uint x,y; for(x=z;x》0;x--) for(y=1;y》0;y--); } void cl() interrupt 3 { clock=!clock; }
|