一、實(shí)驗(yàn)?zāi)康?/font>
1. 掌握A/D轉(zhuǎn)換程序的設(shè)計(jì);
2. 掌握數(shù)據(jù)采集與顯示的應(yīng)用;
3.掌握數(shù)據(jù)處理的方法;
二、實(shí)驗(yàn)內(nèi)容
1. 參照課本P383頁(yè)“0~5V數(shù)字式直流電壓表實(shí)驗(yàn)”程序,并編譯、仿真,見(jiàn)下圖所示。
注意:由于用proteus ISIS仿真時(shí),數(shù)碼管模型顯示的閃爍現(xiàn)象和緩存現(xiàn)象,需要對(duì)其進(jìn)行短延時(shí)和清屏,否則,顯示將出現(xiàn)亂碼現(xiàn)象。可在main()主函數(shù)里加入兩條語(yǔ)句:
Delay(1);
PORTA=0;
(1)修改錯(cuò)誤。
比較程序第25行“ADMUX=0XC7”以及程序第71行“x=(5000*(long)i)/1023”所指參考電壓不一致,導(dǎo)致輸入模擬電壓值與數(shù)碼管顯示電壓值不一致,有哪幾種修改方案。
如把ADMUX=0XC7改為0X07。
(2)調(diào)節(jié)電位器(POT-LOG),觀察數(shù)碼管顯示的電壓值與虛擬直流電壓表顯示的電壓是否一致。
2.將編譯通過(guò)后的程序燒寫(xiě)到單片機(jī)里,調(diào)節(jié)AD電位器,觀看開(kāi)發(fā)板上數(shù)碼管的顯示情況。
注意數(shù)碼管的位選端排列順序,實(shí)驗(yàn)板與課本電路圖中數(shù)碼管排序不同,故需要調(diào)整位選端。
3.如果想觀察ADC轉(zhuǎn)換后的數(shù)字結(jié)果,則需將數(shù)碼管顯示改為:
PORTA=SEG7[adc_val%10];
………
依次類(lèi)推。
三、拓展實(shí)驗(yàn)
把數(shù)碼管顯示改為L(zhǎng)CD1602液晶顯示。(可參考P240“0~5V數(shù)字電壓調(diào)整器”lcd部分程序內(nèi)容)
注意:因使用PA7為輸入端口,而PA口為原電路中LCD1602的數(shù)據(jù)端口,故把數(shù)據(jù)端口改為PC口,注意要把lcd1602液晶的驅(qū)動(dòng)程序“lcd1602_8bit.c”中的語(yǔ)句“#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);
}
}
