继续定时器中断处理的改进。
1、定时器中断程序Timer_Interrupt是这样的。
//定时器中断函数 void Timer_Interrupt(void) { int i=0; timerctl.count ++; for(i=0;i<MAX_TIMER;i++) //扫描所有的定时器 { if(timerctl.timer[i].flag == TIMER_FLAG_USING) { timerctl.count--; if(timerctl.count == 0) //减得时间到了 { fifo8_put(timerctl.timer[i].fifo,timerctl.timer[i].data); //向关联fifo中写入数据 timerctl.timer[i].flag = TIMER_FLAG_ALLOC; //改变标志位 } } } return ; }
程序的弊端在于每次中断里,程序都要循环MAX_TIMER次,查找TMER_FLAG_USING中的定时器中,是否有定时器定时时间到。
改进思想,用nexttimeout变量记录任意时刻的下一个定时时间到。特例:在最开始的时候,没有设置定时器,那么下个定时时间到的值就是大无穷。
看代码,更改timerctl数据描述结构:
struct TIMER { unsigned int timeout,flag,nexttimeout; //设定的定时时间,定时器的状态,下个定时时间到 struct FIFO8 *fifo; //定时器关联的fifo unsigned char data; //当定时时间到时,向fifo中写入的数值 }
更改初始化代码:
void TIMERCTL_Initial(void) { char i=0; timer.count = 0; //基数清零 timerctl.nexttimeout = 0xffffffff; //到下个定时时间到几乎为不可能,也就是还没有设置定时器 这里!!!! for(i=0;i<MAX_TIMER;i++) { timerctl.timer[i].flag = TIMER_FLAG_NOUSE; /*标记为未使用*/ } }
更改定时器设定函数:
//设定timer定时器的定时时间为timeout void timer_settime(struct TIMER* timer,unsigned int timeout) { timer.timeout = timeout + timrctl.count; timer.flag = TIMER_FLAG_USING; //这条语句相当于启动了定时器 //这后面的这句代码 if(timerctl.nexttimeout > timer.timeout) //现在新添加了一个定时器,新添加的定时器定时时间更短,比原先所有设定的定时器都要先到 { timerctl.nexttimeout = timer.timeout; //调整nexttimeout值 } return ; }
再更改定时器中断函数:
//定时器中断函数 void Timer_Interrupt(void) { int i=0; timerctl.count ++; if(timerctl.count > timectl.nexttimeout) return ; //最近的定时时间都没到 timerctl.nexttimeout = 0xffffffff; for(i=0;i<MAX_TIMER;i++) //扫描所有的定时器 { if(timerctl.timer[i].flag == TIMER_FLAG_USING) { if(timerctl.timer[i].timeout <= timerctl.count) { fifo8_put(timerctl.timer[i].fifo,timerctl.timer[i].data); //向关联fifo中写入数据 timerctl.timer[i].flag = TIMER_FLAG_ALLOC; //改变标志位 } else { if(timerctl.timer[i].count < timerctl.nexttimeout) { timerctl.nexttimeout = timerctl.timer[i].count; //更新最小值 } } } } return ; }
以上代码思路很简单,如果现在的计时时间还不到最近的定时时间,那么就退出。如果计数时间超过了最近的定时时间,那么一定就有一个定时器定时时间到了,那么找到这个定时器,接下来呢,就是更新最近的定时时间。上面代码从for(i=0;i<MAX_TIMER;i++) 限定TIMER_FLAG_USING,就是在正在使用的定时器中查找,谁是定时时间到的定时器,其它的就不是,那么它就要去与最近定时时间比较以更新最近定时时间。