上述代码中,定时器的延时存在两个问题。
(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文件里面的代码乱像已显,为此,我们迫切需要第三次的变形。