//AVR單片機課程設(shè)計程序
//名稱:電壓表
//硬件: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) //數(shù)碼管段碼選通
#define BITLK_H PORTA|=BIT(PA4) //數(shù)碼管位選通
//#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轉(zhuǎn)換結(jié)果
//===================數(shù)據(jù)表==============================================
__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; //計數(shù)器清0
OCR0 = 100; //187*256/8M=4.16mS
TIMSK |=0x02; //使能OCIE0
TIFR |=0x02; //清OCIF0中斷標(biāo)識位
}
//=================初始化======================================
void init(void)
{
IO_init();
BEEP_H;
timer0_init();
}
//===============AD轉(zhuǎn)換===========================
void read_adc(void)
{
ADMUX =0x00;//選擇PA0轉(zhuǎn)換通道
ADCSRA=0xE6;//開始AD轉(zhuǎn)換
while ((ADCSRA & 0x10)==0); //等待ad轉(zhuǎn)換結(jié)束
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();
}
//================================================
//------------------------------------------------
//--------------主函數(shù)----------------------------
//------------------------------------------------
void main(void)
{
init();
SFIOR=0X00;
SREG|=0x80;
adc0=1224;
LEDLK_H;
PORTB=0XFF;//滅掉流水燈
LEDLK_L;
while(1)
{
read_adc();
// disp();
voldata=adc0;
}
}
//---------------------------------------------
//---------------------------------------------
//=============================================
//====================定時器T0中斷服務(wù)子程序===================================
#pragma interrupt_handler Timer0_Interrupt:20
void Timer0_Interrupt(void)
{
TCNT0 = 0X00;
TIFR |=0x02; //清OCIF0中斷標(biāo)識位
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;
}
