一、核心基础概念
- 软件定时器本质:基于系统时钟 tick 实现,由内核的 "定时器服务任务" 管理,触发时执行预设回调函数;
- 两种工作模式 :
- 周期模式:定时器到期后自动重装载,持续触发回调(如周期性闪烁);
- 单次模式:定时器到期后停止,仅触发一次回调(如延时 3 秒后恢复默认状态);
- 回调函数限制 :必须是
void vCallback(TimerHandle_t xTimer)格式,不能调用阻塞 API (如vTaskDelay()、xQueueReceive()),仅执行短时间操作。
二、定时器的创建与启动流程
1、包含头文件
#include "FreeRTOS.h"
#include "timers.h" // 定时器API声明在此头文件
2、定义定时器句柄
TimerHandle_t xMyTimer; // 定时器句柄
3、创建定时器(核心步骤)
xMyTimer = xTimerCreate(
"MyTimer", // 定时器名称(仅调试用,可自定义)
pdMS_TO_TICKS(500U), // 定时周期(毫秒转FreeRTOS tick数)
pdTRUE, // 工作模式:pdTRUE=周期,pdFALSE=单次
(void *)0, // 定时器ID(区分多个定时器,自定义)
vMyTimerCallback // 定时器到期回调函数(必须实现)
);
4、启动定时器
创建后需调用xTimerStart()启动,否则定时器不会工作
if(xMyTimer != NULL) {
xTimerStart(xMyTimer, 0); // 0=非阻塞启动,立即返回
}
三、定时器的基本使用(核心操作)
1、 回调函数实现(核心逻辑载体)
// 定时器回调函数(必须符合格式要求)
void vMyTimerCallback(TimerHandle_t xTimer) {
// 示例:翻转LED(仅执行短时间操作)
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
// 注意:不能调用 vTaskDelay()、xQueueReceive() 等阻塞API
}
2、常用API(动态操作定时器)
| 函数 | 作用 | 关键参数说明 |
|---|---|---|
xTimerStart() |
启动定时器(创建后首次启动) | xTicksToWait:启动超时时间(0 = 非阻塞) |
xTimerReset() |
重置定时器(重新开始计时) | 适用于单次模式重复触发,或周期模式重新计时 |
xTimerChangePeriod() |
动态修改定时器周期 | 第 3 个参数为超时时间(如 0 = 非阻塞修改) |
xTimerStop() |
停止定时器(停止后需重新启动才生效) | xTicksToWait:停止超时时间 |
3、周期与 tick 数转换
FreeRTOS 定时器周期以 "tick 数" 为单位,需用pdMS_TO_TICKS(ms)将毫秒转换为 tick 数(适配系统时钟频率):
// 500毫秒 → 对应tick数(自动适配 configTICK_RATE_HZ)
pdMS_TO_TICKS(500U)
四、例子------单次
时器启动后只触发一次回调函数,触发完成后就自动停止,不会重复执行
创建
TimerHandle_t xSwitchTimer; // 模式切换定时器(单次模式)
void vSwitchTimerCallback(TimerHandle_t xTimer); // 模式切换定时器回调函数
// 1.2 模式切换定时器(单次模式,触发后只执行一次)
xSwitchTimer = xTimerCreate(
"SwitchTimer",
pdMS_TO_TICKS(SWITCH_TIMER_DELAY),
pdFALSE, // 单次模式
(void *)1, // 定时器ID=1
vSwitchTimerCallback
);
回调函数
/* 模式切换定时器回调函数:3秒后执行,恢复默认模式 */
void vSwitchTimerCallback(TimerHandle_t xTimer)
{
// 定时器到期,恢复LED默认模式
xCurrentLedMode = LED_MODE_DEFAULT;
}
xSwitchTimer是单次模式 ,代码中没有在初始化时启动它,而是在按键任务中通过 xTimerReset() 启动 / 重置。
这里我要根据按键触发启动及再次启动它,所以增加了按下按键后再次开启它
xTimerReset(xSwitchTimer, 0); // 重置定时器 若定时器已在运行,重置为3秒后触发
五、例子------周期
创建
TimerHandle_t xBlinkTimer; // 基础闪烁定时器(周期模式)
void vBlinkTimerCallback(TimerHandle_t xTimer); // 闪烁定时器回调函数
// 1.1 基础闪烁定时器(周期模式,自动重装载)
xBlinkTimer = xTimerCreate(
"BlinkTimer", // 定时器名称(仅调试用)
pdMS_TO_TICKS(BLINK_TIMER_PERIOD), // 周期(毫秒转FreeRTOS ticks)
pdTRUE, // 模式:pdTRUE=周期模式,pdFALSE=单次模式
(void *)0, // 定时器ID(区分多个定时器)
vBlinkTimerCallback // 定时器到期回调函数
);
启动
xTimerStart(xBlinkTimer, 0); // 启动闪烁定时器(0=非阻塞启动)
回调函数
/* 定时器回调函数:定时器到期时执行(控制LED翻转)xBlinkTimer */
void vBlinkTimerCallback(TimerHandle_t xTimer)
{
// 根据当前LED模式,调整闪烁周期
switch(xCurrentLedMode) {
case LED_MODE_FAST:
// 快闪:修改定时器周期为200ms
xTimerChangePeriod(xBlinkTimer, pdMS_TO_TICKS(200U),0);
break;
case LED_MODE_SLOW:
// 慢闪:修改定时器周期为800ms
xTimerChangePeriod(xBlinkTimer, pdMS_TO_TICKS(800U),0);
break;
case LED_MODE_DEFAULT:
default:
// 默认:恢复500ms周期
xTimerChangePeriod(xBlinkTimer, pdMS_TO_TICKS(500U),0);
break;
}
// 翻转LED(回调函数中避免长时间操作,仅执行简单逻辑)
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_10);
}