上述代码中,定时器的延时存在两个问题。
(1) 延时程序精度不高。在不同mcu和不同的外部晶振,这个函数都需要修改。当这个系统开启了更多的中断时,这个函数精度受到的影响就是随机性的。
(2) while+for的延时方法,属于一种“硬延时”,生生地耗掉mcu的运行资源。在实时性要求极高的嵌入式领域,这种做法显然不合时宜。
综上,在本次进化,我们需要引进系统的定时器中断功能。它至少涉及两个函数。
/***** LED 跑马灯(从右至左)***************************/
……………….
/**********************************************************/
#define XTAL (36864000UL)
#define TIMER_1MS (XTAL/12UL/1000UL)
/*--------------------------------*/
static volatile unsigned char flag_80ms = 0;
static void timer1(void) interrupt 3 using 1
{
static unsigned char tcnt = 0;
TCNT1 += (-TIMER_1MS);/* 为何如此写法,详见章节…*/
if (++tcnt >= LIGHT_INTERVAL_TIME)
{
tcnt = 0;
flag_80ms = 1;
}
}
void timer_init(void)
{
TMOD = 0x11; // timer0 16-bit, timer1 16-bit
TCNT1 = (-TIMER_1MS);
TR1 = 1;
IE |= 0x0A; // ???? ial 0, enable timer 1, ex0,1
}
/*********************************************************/
void main(void)
{
led_light_init();
timer_init();
while (1)
{
if (flag_80ms)
{
flag_80ms = 0;
led_light_right2left();
}
}
}
代码3跑马灯的第二次变形
加上定时器中断后,定时器的精度提高了,mcu的运算资源也极大的释放。然而,我们不得不设置了一个全局变量“flag_80ms”,用来沟通main和定时中断,增加一个内部全局变量tcnt,用来累计1ms定时功能。此时,main.c文件里面的代码乱像已显,为此,我们迫切需要第三次的变形。