软件定时器简介
定时器:从一个指定时刻开始,经过一个指定事件,触发一个超时事件,我们可以自定义定时器的周期,就类似于闹钟。
硬件定时器:芯片本身自带的定时器模块,硬件定时器精度高,每次定时事件到达后就自动触发一个中断,我们在中断服务函数中处理信息。
软件定时器:具有定时功能的软件,可设置周期,指定事件到达后调用回调函数,在回调函数中处理信息。
很显然,软件定时器相较于硬件定时器来说,数量可以随意创建不固定且成本低,但是精度相较来说没那么高且容易被打断。
软件定时器特点
- 可任意裁剪:需要使能软件定时器的话,只需要将对应的宏configUSE_TIMERS
置1 - 可设置单次和周期:软件定时器可以设置成单次定时器和周期定时器
软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的 API 函数,例如 vTaskDelay()。
软件定时器服务任务:在调用函数 vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。
软件定时器服务任务作用如下,
- 负责软件点定时器的超时的逻辑判断
- 调用超时软件定时器的超时回调函数
- 处理软件定时器的命令队列
命令队列:FreeRTOS提供了许多软件定时器相关的 API 函数,这些 API 函数大部分都是往定时器的队列中写入消息,这个队列叫做软件定时器命令队列,是提供给 FreeRTOS 中的软件定时器使用的,用户是不能直接访问的
软件定时器配置
以下时软件定时器的相关配置,都是由FreeRTOS的宏定义进行配置,
- 配置宏configUSE_TIMERS为1,在启动任务调度器时会自动创建软件定时器服务
- 软件定时器的优先级配置为31(最大)
- 定期器的命令队列长度配置为5
备注: 软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定定时器的超时回调函数本身不是任务,定时器的回调函数不能影响其他创建的软件定时器。
软件定时器状态
软件定时器有以下两种状态,
休眠态:休眠态软件定时器可以通过其句柄被引用,但是因为没有运行,所以其定时超时回调函数不会被执行。
运行态:处于运行态或在上次定时超时后再次定时超时的软件定时器,会执行其定时超时回调函数。
备注:新创建的软件定时器是处于休眠状态的,也就是未运行的。
软件定时器有以下两种模式,
单次定时器: 单次定时器一旦定时超时,只会执行一次其软件定时器超时回调函数,超时后可以被手动重新开启,但单次定时器不会自动重新开启定时。
周期定时器: 周期定时器一旦被开启,会在每次超时时,自动地重新启动定时器,从而周期地执行其软件定时器回调函数。
示意图如下,
两种工作模式的软件定时器状态的转换图如下,
单次定时器
周期定时器
软件定时器函数
函数分为5类,分别是创建软件定时器,开启软件定时器,停止软件定时器,复位软件定时器,修改软件定时器的定时时间。
创建软件定时器
xTimerCreate():
TimerHandle_t xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );
参数:
- pcTimerName:软件定时器的名字
- xTimerPeriodInTicks:定时超时时间,单位是系统的时钟节拍
- uxAutoReload:定时器模式,选择pdTRUE就是周期定时器,反之是单次定时器
- pvTimerID:定时器ID,用于多个软件定时器公用一个超时回调函数
- pxCallbackFunction:软件定时器回调函数
返回值为NULL的话就是创建失败,返回句柄创建成功。
开启软件定时器
xTimerStart():
BaseType_t xTimerStart( TimerHandle_t xTimer,
const TickType_t xTicksToWait );
参数:
- xTimer:待开启的软件定时器句柄
- xTicksToWait:等待超时时间
返回值为pdPASS的话就是开启成功,返回pdFAIL开启失败。
创建软件定时器内部实现如下,
停止软件定时器
xTimerStop():
BaseType_t xTimerStop( TimerHandle_t xTimer,
const TickType_t xTicksToWait );
参数:
- xTimer:待停止的软件定时器句柄
- xTicksToWait:等待超时时间
返回值为pdPASS的话就是停止成功,返回pdFAIL停止失败。
复位软件定时器
xTimerReset():
BaseType_t xTimerReset( TimerHandle_t xTimer,
const TickType_t xTicksToWait );
参数:
- xTimer:待复位的软件定时器句柄
- xTicksToWait:等待超时时间
返回值为pdPASS的话就是复位成功,返回pdFAIL复位失败。
备注:该功能可以让软件定时器重新开启定时,复位后软件定时器以复位时时刻作为开启时刻重新定时。
修改软件定时器定时时间
xTimerChangePeriod():
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
const TickType_t xNewPeriod,
const TickType_t xTicksToWait );
参数:
- xTimer:待更新的软件定时器句柄
- xNewPeriod:新的定时超时时间,单位是系统时钟节拍
- xTicksToWait:等待超时时间
返回值为pdPASS的话就是复位成功,返回pdFAIL复位失败。