简介这里先介绍一下软件定时器和硬件定时器的区别,对应的定时器中断处理函数会被执行。硬件定时器一般还有其他功能,如PWM输出、输入捕捉等。但缺点是硬件定时器数量少!!软件定时器:软件定时器允许设置一个时间段。当设定的时间到达时,将执行指定的功能。定时器调用的函数称为定时器的回调函数。两次执行回调函数之间的时间间隔称为定时器的计时周期。简而言之,回调函数将在定时器的计时周期到时执行。FreeRTOS中有一个专门的软件定时器功能,我们可以简单的在MCU中实现“软件定时器”如下:voidtimer_1000ms(void){printf("timer_1000ms\r\n");}intmain(void){statictimer_tick=0;timer_tick=systick_ms;while(){if((systick_ms-timer_tick)>1000){timer_tick=systick_ms;timer_1000ms();}}}这是一个简单的软件定时器,没错,这是一个特别精简版的软件定时器。当然它也有缺点,比如systick_ms每1ms加1,所以软件定时器的精度是以ms为单位的,如果while(1)中阻塞了其他代码,那么软件定时器也会被阻塞。这个简单的软件定时器毕竟“简单”。可以自己打包丰富,也可以参考现有的开源方案:MultiTimer,一个可无限扩展的软件定时器。MultiTimer是一个软件定时器扩展模块,可以无限扩展你需要的定时器任务,替代传统的标志位判断方式,更优雅方便的管理程序的时间触发定时。开源地址:https://github.com/0x1abin/MultiTimer。MultiTimerMultiTimer的设计比较简单,只有2个文件,而且只有4个函数,一共82行代码,稍微下点功夫就能看懂。迁移步骤配置系统时间参考接口,安装定时器驱动uint64_tPlatformTicksGetFunc(void){/*平台实现*/}MultiTimerInstall(PlatformTicksGetFunc);实例化一个定时器对象MultiTimertimer1;设置计时时间,超时回调处理函数,用户上下指针,启动定时器intMultiTimerStart(&timer1,uint64_ttiming,MultiTimerCallback_tcallback,void*userData);调用定时器后台处理函数intmain(intargc,char*argv[]){...while(1){...MultiTimerYield();具体怎么移植我就不做手把手的教程了。STM32F207中移植的项目开源地址:开源地址:https://github.com/strongercjd/STM32F207VCT6/tree/master/23-Timer-MultiTimer。我们来分析一下MultiTimer。移植第一步,配置系统时间参考接口,安装定时器驱动。uint64_tPlatformTicksGetFunc(void){/*平台实现*/}MultiTimerInstall(PlatformTicksGetFunc);查看MultiTimerInstall函数原型。typedefuint64_t(*PlatformTicksFunction_t)(void);staticPlatformTicksFunction_tplatformTicksFunction=NULL;intMultiTimerInstall(PlatformTicksFunction_tticksFunc){platformTicksFunction=ticksFunc;return0;}这其实就是函数指针实现的回调函数,其实就是MultiTimer的一个计数器。这个开源项目除了回调函数,还是单链表的好例子。学习数据结构比较繁琐。这个开源项目是单链表的一个很好的应用。不太了解的同学可以学习一下。我们看一下删除部分代码链表:/*从列表中删除*/break;}}插入链表:for(nextTimer=&timerList;;nextTimer=&(*nextTimer)->next){if(!*nextTimer){timer->next=NULL;*nextTimer=定时器;休息;}if(timer->deadline<(*nextTimer)->deadline){timer->next=*nextTimer;*nextTimer=定时器;休息;}}遍历链表:MultiTimer*entry=timerList;for(;entry;entry=entry->next){/*排序后的列表,只处理前面的部分。*/if(platformTicksFunction()
