一、實驗目的
1. 掌握A/D轉換程序的設計;
2. 掌握數據采集與顯示的應用;
3.掌握數據處理的方法;
二、實驗內容
1. 參照課本P383頁“0~5V數字式直流電壓表實驗”程序,并編譯、仿真,見下圖所示。
注意:由于用proteus ISIS仿真時,數碼管模型顯示的閃爍現象和緩存現象,需要對其進行短延時和清屏,否則,顯示將出現亂碼現象。可在main()主函數里加入兩條語句:
Delay(1);
PORTA=0;
(1)修改錯誤。
比較程序第25行“ADMUX=0XC7”以及程序第71行“x=(5000*(long)i)/1023”所指參考電壓不一致,導致輸入模擬電壓值與數碼管顯示電壓值不一致,有哪幾種修改方案。
如把ADMUX=0XC7改為0X07。
(2)調節電位器(POT-LOG),觀察數碼管顯示的電壓值與虛擬直流電壓表顯示的電壓是否一致。
2.將編譯通過后的程序燒寫到單片機里,調節AD電位器,觀看開發板上數碼管的顯示情況。
注意數碼管的位選端排列順序,實驗板與課本電路圖中數碼管排序不同,故需要調整位選端。
3.如果想觀察ADC轉換后的數字結果,則需將數碼管顯示改為:
PORTA=SEG7[adc_val%10];
………
依次類推。
三、拓展實驗
把數碼管顯示改為LCD1602液晶顯示。(可參考P240“0~5V數字電壓調整器”lcd部分程序內容)
注意:因使用PA7為輸入端口,而PA口為原電路中LCD1602的數據端口,故把數據端口改為PC口,注意要把lcd1602液晶的驅動程序“lcd1602_8bit.c”中的語句“#define DataPort PORTA”改為“#define DataPort PORTC”。Proteus ISIS仿真圖如下圖。
四、附使用LCD1602顯示ADC參考程序
#include <iom16v.h> #include "lcd1602_8bit.c" uchar const title[]={"0-5v D_voltager"}; #define uchar unsigned char #define uint unsigned int uint adc_val,dis_val; uchar i,cnt; /************************************************/ void port_init(void) { PORTA = 0x7F; DDRA = 0x7F; PORTB = 0xFF; DDRB = 0xFF; PORTC = 0xFF; DDRC = 0xFF; PORTD = 0xFF; DDRD = 0xFF; } /************************************************/ void adc_init(void) { ADCSRA = 0xE3; ADMUX = 0x47; } //*************************** void timer0_init(void) { TCNT0 = 0x83; TCCR0 = 0x03; TIMSK = 0x01; } /*********************************************/ void init_devices(void) { port_init(); timer0_init(); adc_init(); SREG =0x80; } //*************************** #pragma interrupt_handler timer0_ovf_isr:10 void timer0_ovf_isr(void) { TCNT0 = 0x83; cnt++; } //========================= uint ADC_Convert(void) {uint temp1,temp2; adc_init(); temp1=(uint)ADCL; temp2=(uint)ADCH; temp2=(temp2<<8)+temp1; return(temp2); } /**************************/ uint conv(uint i) { long x; uint y; x=(5000*(long)i)/1023; y=(uint)x; return y; } void delay(uint k) { uint i,j; for(i=0;i<k;i++) { for(j=0;j<1141;j++); } } /***********************/ void main(void) { init_devices(); Delay_nms(400); DDRA=0X7F;PORTA=0X7F; DDRC=0XFF;PORTC=0X00; DDRB=0XFF;PORTB=0X00; InitLcd(); ePutstr(1,0,title); DisplayOneChar(0,1,'A'); DisplayOneChar(1,1,'D'); DisplayOneChar(2,1,'C'); DisplayOneChar(3,1,'7'); DisplayOneChar(4,1,':'); DisplayOneChar(11,1,'.'); DisplayOneChar(15,1,'V'); while(1) { if(cnt>100) { adc_val=ADC_Convert(); dis_val=conv(adc_val); cnt=0; } delay(10); DisplayOneChar(5,1,(adc_val/1000)+0x30); DisplayOneChar(6,1,(adc_val/100)%10+0x30); DisplayOneChar(7,1,(adc_val/10)%10+0x30); DisplayOneChar(8,1,(adc_val%10)+0x30); DisplayOneChar(10,1,(dis_val/1000)+0x30); DisplayOneChar(12,1,(dis_val/100)%10+0x30); DisplayOneChar(13,1,(dis_val/10)%10+0x30); DisplayOneChar(14,1,(dis_val%10)+0x30); } }