//電路里有4個七段LED,用此程序,每個LED的刷新周期為200/4=50Hz。
//程序里實時改變DispResult的值,顯示就會相應改變。
#include
#include
unsigned char
table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char LEDRefresh=0;
unsigned char DispResult=0;
unsigned char LedLoop=0;
void port_init(void)
{
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00;
DDRC = 0x01;
PORTD = 0x00;
DDRD = 0xFF;
}
//電路所用時鐘為Mega8內部8M時鐘。
//TIMER1 initialize - prescale:1
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 200Hz
// actual value: 200
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x63; //setup
TCNT1L = 0xC0;
OCR1AH = 0x03;
OCR1AL = 0xE8;
OCR1BH = 0x03;
OCR1BL = 0xE8;
ICR1H = 0x03;
ICR1L = 0xE8;
TCCR1A = 0x00;
TCCR1B = 0x01; //start Timer
}
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
TCNT1H = 0x63; //reload counter high value
TCNT1L = 0xC0; //reload counter low value
LEDRefresh=1;//刷新顯示標志
/*分別選通四個LED*/
LedLoop++;
LedLoop=LedLoop&0x03;
}
//輸入?yún)?shù)為通道,和數(shù)字。
void LedDisp (unsigned char ch,unsigned char num)
{
unsigned char channel;
unsigned char number;
number = num;
PORTB|=0x07;
PORTC|=0x01;//把所有的LED都關掉。
switch(ch)
{
case 1:PORTB&=~0x04;break;//選通第一個LED
case 2:PORTB&=~0x02;break;//選通第二個LED
case 3:PORTB&=~0x01;break;//選通第三個LED
case 4:PORTC&=~0x01;break;//選通第四個LED
default : break;
}
PORTD=~table[number];//向LED里放數(shù)據(jù)。
}
void CheckTime()
{
/***********顯示任務,每5ms執(zhí)行一次***************/
if(LEDRefresh==1)
{
switch(LedLoop)
{
case 0:LedDisp(1,DispResult%10);break;//第一個LED顯示個位
case 1:LedDisp(2,DispResult/10%10);break;//第二個LED顯示十位
case 2:LedDisp(3,DispResult/100%10);break;//第三個LED顯示百位
case 3:LedDisp(4,DispResult/1000%10);break;//第四個LED顯示千位
default: break;
}
LEDRefresh=0;
}
}
void main()
{
CLI(); //dISAble all interrupts
DispResult=2001;
port_init();
timer1_init();
MCUCR = 0x08;
// GICR = 0x80;//打開中斷1
TIMSK = 0x04; //timer interrupt sources
SEI(); //re-enable interrupts
while(1)
{
CheckTime();
}
}