//电路里有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;
}
//输入参数为通道,和数字。
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里放数据。
}
void CheckTime()
{
/***********显示任务,每5ms执行一次***************/
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();
}
}
上一篇:ATMEGA16 ADC模数转换示例程序
下一篇:AVR的外部中断INT示例程
推荐阅读最新更新时间:2024-03-16 15:49