/*
************************************************************
程序介绍:基于Atmega8的数字钟,实现六位显示“00:00:00”
************************************************************
*/
#i nclude <avr/io.h>
#i nclude <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define seg_code PORTD //数据口
#define seg_com PORTC //位选通
/*************************************************************************/
uchar seven_seg[10]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
uchar scan[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,};
/*************************************************************************/
typedef struct
{
 uchar hour;
 uchar minute;
 uchar second;
} time;
uint timer0_num=0;
uchar com=0;
time now;
/*
************************************************************
函数功能:端口初始化
输入参数:无
输出参数:无
返 回 值:无
************************************************************
*/
void PORT_Init(void)
{
 DDRB=0XFF;
 DDRC=0XFF;
 DDRD=0XFF;
 PORTB=0XFF;
 PORTC=0XFF;
 PORTD=0XFF;
}
/*
************************************************************
函数功能:定时器0初始化
输入参数:无
输出参数:无
返 回 值:无
************************************************************
*/
void TIMER0_Init(void)
{
 TCCR0=0X02; //定时器0时钟源8分频,大约延时2ms(8*256/1000000)
 TCNT0=0X00; //定时器赋初值
 TIMSK=_BV(TOIE0); //开定时器0
}
/*
************************************************************
函数功能:主函数
输入参数:无
输出参数:无
返 回 值:无
************************************************************
*/
void main (void)
{
 TIMER0_Init();
 PORT_Init();
 sei();
 while (1);
}
/*
************************************************************
函数功能:定时器0溢出中断函数,时间的显示变化都在这里面
输入参数:无
输出参数:无
返 回 值:无
************************************************************
*/
ISR(TIMER0_OVF_vect)
{
 timer0_num++;
 if (timer0_num==500)  //定时到1s时,执行相应的显示时间操作
{
 timer0_num=0;
 now.second++;
 if(now.second==60)
 {
 now.minute++;
 now.second=0;
 if(now.minute==60)
{
 now.hour++;
 now.minute=0;
 if(now.hour==24)
 now.hour=0;
 }
 }
 }
 switch(com)
 {
 case 0 : seg_code=~seven_seg[now.second%10];break;
 case 1 : seg_code=~seven_seg[now.second/10];break;
 case 2 : seg_code=~seven_seg[now.minute%10];break;
 case 3 : seg_code=~seven_seg[now.minute/10];break;
 case 4 : seg_code=~seven_seg[now.hour%10];break;
 case 5 : seg_code=~seven_seg[now.hour/10];break;
 default: break;
 }
 seg_com=scan[com];
 com++;
 if(com==6) com=0;
}