/*
名称:100000s以内的计时程序
*/
///说明:在六只数码管上完成00000.0~99999.9S计时
#define F_CPU 4000000UL ///4MHz晶振
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define INT8U unsigned char
#define INT16U unsigned int
///共阴数码管0~9的数字段码
const INT8U SEG_CODE[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
///6只数码管上显示的数字缓冲
INT8U Digits_Buffer[] = {0,0,0,0,0,0};
///刷新显示子程序
void Show_Count_ON_DSY()
{
INT8U i;
for(i = 0;i <= 5;i++)
{
PORTC = 0x00; ///暂时关闭段码
PORTA = ~_BV(5 - i); ///输出位码
PORTC = SEG_CODE[Digits_Buffer[i]]; ///输出段码
if(i == 1)
PORTC |= 0x80; ///在个位数上加小数点
_delay_ms(3); ///位间延时
}
}
///主程序
int main()
{
DDRA = 0xff; PORTA = 0xff; ///配置端口
DDRC = 0xff; PORTA = 0xff;
DDRD = 0x00; PORTD = 0xff;
MCUCR = 0x02; ///INT0为下降沿触发
GICR = 0x40; ///INT0中断使能
TCNT1 = 65535 - F_CPU/8*0.1; ///0.1S定时(T1预设8分频在INT0中断中完成)
TIMSK = _BV(TOIE1); ///允许T1定时器溢出中断
sei(); ///开中断
while(1)
Show_Count_ON_DSY(); ///持续刷新显示
}
///T1定时器溢出中断实现计时
ISR(TIMER1_OVF_vect)
{
INT8U i;
TCNT1 = 65535 - F_CPU/8*0.1; ///重设0.1s定时初值
Digits_Buffer[0]++; ///0.1s位累加
for(i = 0;i <= 5;i++) ///进位处理
{
if(Digits_Buffer[i] == 10)
{
Digits_Buffer[i] = 0;
///如果是0~4位则分别向高一位进位
if(i != 5)
Digits_Buffer[i + 1]++;
}
///循环过程中如果某个低位没有进位,则循环可提前结束
else
break;
}
}
///INT0中断函数完成K1按键的3种操作
ISR(INT0_vect)
{
INT8U i;
///按键操作标志:0停止,1开始,2暂停
static INT8U KeyOperation = 0;
///每次按键时,操作标志在0,1,2中循环选择
if(++KeyOperation == 3)
KeyOperation = 0;
switch(KeyOperation)
{
case 0: TCCR1B = 0x00; ///停止(清0)
for(i = 0;i < 6;i++)
Digits_Buffer[i] = 0;
break;
case 1: TCCR1B = 0x02; ///开始计时
break;
case 2: TCCR1B = 0x00; ///暂停计时
break;
}
}
这是程序
|