//AVR單片機課程設計程序
//名稱:電壓表
//硬件:AVR-ATMEGA16 實驗板 8MHz 晶振
//編寫人:李春起
//編寫時間:2010。06。26
//修改日志:
#include<iom16v.h> #include <macros.h> //-------------位拉高宏-------------------------------------------- #define ADC0_H PORTA|=BIT(PA0) #define ADC1_H PORTA|=BIT(PA1) #define LEDLK_H PORTA|=BIT(PA2) //流水燈選通 #define SEGLK_H PORTA|=BIT(PA3) //數碼管段碼選通 #define BITLK_H PORTA|=BIT(PA4) //數碼管位選通 //#define 18B20_H PORTA|=BIT(PA5) #define BEEP_H PORTA|=BIT(PA6) //蜂鳴器 #define CUSB_H PORTA|=BIT(PA7) //-------------位拉低宏-------------------------------------------- #define ADC0_L PORTA&=~BIT(PA0) #define ADC1_L PORTA&=~BIT(PA1) #define LEDLK_L PORTA&=~BIT(PA2) #define SEGLK_L PORTA&=~BIT(PA3) #define BITLK_L PORTA&=~BIT(PA4) //#define 18B20_L PORTA&=~BIT(PA5) #define BEEP_L PORTA&=~BIT(PA6) #define CUSB_L PORTA&=~BIT(PA7) //----------單獨按鍵宏定義-------------------------------- #define S1 (PIND&0X01)==0 #define S2 (PIND&0X02)==0 #define S3 (PIND&0X04)==0 #define S4 (PIND&0X08)==0 #define NOP() asm("nop") #define uchar unsigned char #define uint unsigned int //============全局變量====================================== uint adc0,flag,voldata;//AD轉換結果 //===================數據表============================================== __flash uchar SEG[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff}; //===============mS延時子程序============================================ void delayms(uint m) { uint i,j; for(i=0;i<m;i++) { for(j=0;j<1141;j++); } } //==================IO口初始化======================================= void IO_init(void) { DDRA = 0Xfe; DDRB = 0Xff; DDRC = 0XFF; DDRD = 0XFF; PORTD= 0XFF; } //====================定時器T0初始化=================================== void timer0_init(void) { TCCR0 = 0x0c; //256分頻 CTC模式 TCNT0 = 0x00; //計數器清0 OCR0 = 100; //187*256/8M=4.16mS TIMSK |=0x02; //使能OCIE0 TIFR |=0x02; //清OCIF0中斷標識位 } //=================初始化====================================== void init(void) { IO_init(); BEEP_H; timer0_init(); } //===============AD轉換=========================== void read_adc(void) { ADMUX =0x00;//選擇PA0轉換通道 ADCSRA=0xE6;//開始AD轉換 while ((ADCSRA & 0x10)==0); //等待ad轉換結束 adc0 = ADCL; adc0 |= ADCH<<8; } //===================消殘影======================================== void clear_LED(void) { SEGLK_H; PORTB=0x00; SEGLK_L; } //===================顯示========================== void disp(void) { SEGLK_H;PORTB=SEG[adc0%10];SEGLK_L;BITLK_H;PORTB=0xdf;BITLK_L;delayms(3);clear_LED(); SEGLK_H;PORTB=SEG[(adc0/10)%10];SEGLK_L;BITLK_H;PORTB=0xef;BITLK_L;delayms(3);clear_LED(); SEGLK_H;PORTB=SEG[(adc0/100)%10];SEGLK_L;BITLK_H;PORTB=0xf7;BITLK_L;delayms(3);clear_LED(); SEGLK_H;PORTB=SEG[adc0/1000];SEGLK_L;BITLK_H;PORTB=0xfb;BITLK_L;delayms(3);clear_LED(); SEGLK_H;PORTB=SEG[0];SEGLK_L;BITLK_H;PORTB=0xfd;BITLK_L;delayms(3);clear_LED(); SEGLK_H;PORTB=SEG[0];SEGLK_L;BITLK_H;PORTB=0xfe;BITLK_L;delayms(3);clear_LED(); clear_LED(); } //================================================ //------------------------------------------------ //--------------主函數---------------------------- //------------------------------------------------ void main(void) { init(); SFIOR=0X00; SREG|=0x80; adc0=1224; LEDLK_H; PORTB=0XFF;//滅掉流水燈 LEDLK_L; while(1) { read_adc(); // disp(); voldata=adc0; } } //--------------------------------------------- //--------------------------------------------- //============================================= //====================定時器T0中斷服務子程序=================================== #pragma interrupt_handler Timer0_Interrupt:20 void Timer0_Interrupt(void) { TCNT0 = 0X00; TIFR |=0x02; //清OCIF0中斷標識位 clear_LED(); switch(flag) { case 0:{SEGLK_H;PORTB=SEG[voldata%10];SEGLK_L; BITLK_H;PORTB=0xdf;BITLK_L;flag=1;}break; case 1:{SEGLK_H;PORTB=SEG[(voldata/10)%10];SEGLK_L; BITLK_H;PORTB=0xef;BITLK_L;flag=2;}break; case 2:{SEGLK_H;PORTB=SEG[(voldata/100)%10];SEGLK_L; BITLK_H;PORTB=0xf7;BITLK_L;flag=3;}break; case 3:{SEGLK_H;PORTB=SEG[voldata/1000];SEGLK_L; BITLK_H;PORTB=0xfb;BITLK_L;flag=0;}break; default:break; }