第15章 软件定时器
约 1233 字大约 4 分钟
2026-01-19
15.1 核心知识点
概述:
软件定时器是一种轻量级的时间管理工具,用于在任务中创建和管理定时器。
软件定时器是基于 FreeRTOS 内核提供的时间管理功能实现的,允许开发者创建、启动、停止、删除和管理定时器,从而实现在任务中对时间的灵活控制。软件定时器三种状态:
未创建(Uncreated):软件定时器被创建之前的状态。
在这个状态下,定时器的数据结构已经被定义,但尚未通过 xTimerCreate() 函数创建。
已创建(Created):软件定时器已被成功创建,但尚未启动。
在这个状态下,可以对定时器进行配置,如设置定时器的周期、回调函数等,但定时器并未开始计时。
已运行(Running):软件定时器已经被启动,正在运行中。
在这个状态下,定时器会按照预定的周期定时触发超时事件,执行注册的回调函数。两种定时器类型:
一次性定时器(One-shot Timer):
这种定时器在触发一次超时后就会停止,不再执行。
适用于只需在特定时间执行一次任务或动作的场景。
周期性定时器(Periodic Timer):
这种定时器会在每个超时周期都触发一次,循环执行。
适用于需要在固定的时间间隔内重复执行任务或动作的场景。相关宏
configUSE_TIMERS 是否启用软件定时器功能
configTIMER_TASK_PRIORITY 软件定时器任务的优先级
configTIMER_QUEUE_LENGTH 软件定时器命令队列的长度
configTIMER_TASK_STACK_DEPTH 软件定时器任务的栈空间大小相关类型:
TimerHandle_t 定时器句柄
TimerCallbackFunction_t 定时器回调函数的类型相关函数
xTimerCreate() 动态方式创建软件定时器
xTimerCreateStatic() 静态方式创建软件定时器
xTimerStart() 开启软件定时器定时
xTimerStartFromISR() 在中断中开启软件定时器定时
xTimerStop() 停止软件定时器定时
xTimerStopFromISR() 在中断中停止软件定时器定时
xTimerReset() 复位软件定时器定时
xTimerResetFromISR() 在中断中复位软件定时器定时
xTimerChangePeriod() 更改软件定时器的定时超时时间
xTimerChangePeriodFromISR() 在中断中更改定时超时时间15.2 案例
① 需求
创建两个定时器:一次性定时器和周期性定时器。
task1:检测到SW3按下,启动一次性定时器,检测到SW4按下,启动周期性定时器② 代码
FreeRTOSConfig.h
添加配置项:
// 启动软件定时器
#define configUSE_TIMERS 1
// 设置定时器任务的优先级
#define configTIMER_TASK_PRIORITY 2
// 设置定时器任务的栈空间大小
#define configTIMER_TASK_STACK_DEPTH 128
// 设置定时器的命令队列的长度
#define configTIMER_QUEUE_LENGTH 10App_Task.h
包含头文件:
#include "timers.h"App_Task.c
#include "App_Task.h"
// 任务1 ------------------------------------
// 任务1函数的原型
void task1_callback(void *pvParameters);
// 任务1名称
#define TASK1_NAME "task1"
// 任务1堆栈大小
#define TASK1_STACK_SIZE 128
// 任务1的优先级
#define TASK1_PRIORITY 1
// 任务1的句柄
TaskHandle_t task1_handle;
// 软件定时器1 ------------------------------
// 定义软件定时器1的回调函数的原型
void timer1_callback(TimerHandle_t xTimer );
// 软件定时器1的句柄
TimerHandle_t timer1_handle;
// 软件定时器2
// 定义软件定时器2的回调函数的原型
void timer2_callback(TimerHandle_t xTimer );
// 定义软件定时器2的句柄
TimerHandle_t timer2_handle;
/**
* @brief 启动 FreeRTOS 任务管理
*
*/
void App_Task_Start(void)
{
// 进入临界区
taskENTER_CRITICAL();
// 创建任务1
xTaskCreate(task1_callback, TASK1_NAME, TASK1_STACK_SIZE, NULL, TASK1_PRIORITY, &task1_handle) == pdPASS ? printf("任务1创建成功! \n") : printf("任务1穿件失败! \n");
// 创建定时器1,实现一次性定时器
timer1_handle = xTimerCreate("timer1", pdMS_TO_TICKS(1000), pdFALSE, (void *)1, timer1_callback);
timer1_handle == NULL ? printf("定时器1创建失败! \n") : printf("定时器1创建成功! \n");
// 创建定时器2,实现周期定时器
timer2_handle = xTimerCreate("timer2", pdMS_TO_TICKS(2000), pdTRUE, (void *)2, timer2_callback);
timer2_handle == NULL ? printf("定时器2创建失败! \n") : printf("定时器2创建成功! \n");
taskEXIT_CRITICAL();
// 启动任务调度器 ( vTaskStartScheduler() 后面的代码不会被执行)
printf("任务调度器启动... \n");
vTaskStartScheduler();
}
// 任务1函数的实现
void task1_callback(void *pvParameters)
{
printf("任务1启动... \n");
while (1)
{
// 检测按键
switch (Int_Key_IsDetect())
{
case 3:
// 按键3被按下,启动软件定时器1(一次性定时器)
printf("任务1: 按键3被按下, 启动软件定时器1(一次性定时器) \n");
xTimerStart(timer1_handle, 0);
break;
case 4:
// 按键4被按下,启动软件定时器2(周期定时器)
printf("任务1: 按键4被按下, 启动软件定时器2(周期定时器) \n");
xTimerStart(timer2_handle, 0);
break;
default:
break;
}
}
}
// 软件定时器1的回调函数的实现
void timer1_callback(TimerHandle_t xTimer )
{
printf("Timer1 Runing ... \n");
}
// 软件定时器2的回调函数的实现
void timer2_callback(TimerHandle_t xTimer )
{
printf("Timer2 Runing ... \n");
}