用户可自定义定时器的周期,当指定时间到达后调用回调函数,用户在回调函数中处理信息
硬件定时器:
芯片自带的定时器模块,精度高,能触发中断,用户在中断服务函数中处理信息
a.在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。软件定时器服务任务,主要负责软件定时器超时的逻辑判断、调用超时软件定时器的超时回调函数以及处理软件定时器命令队列。且回调函数中不能有延时阻塞之类的函数vTaskDelay()、vTaskDelayUntil()等
b.软件定时器刚创建的时候属于休眠态,需要激活才能变为运行态,休眠态其回调函数不会被执行
a.在FreeRTOSConfig.h中把configCSE_TIMERS置1
b.configTIMER_TASK_PRIORITY设为31,就是把服务任务的优先级设为最高
c.configTIMER_QUEUE_LENGTH设为5,把命令队列长度设为5,能接收多个命令
动态创建软件定时器 xTimerCreate()
TimerHandle_t xTimerCreate(
const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction);
参数:
软件定时器名,定时器超时时间(系统时钟节拍),定时器模式(pdTRUE 周期定时器,pdFALSE 单次定时器),软件定时器ID(用于多个软件定时器公用一个超时回调函数),软件定时器超时回调函数
返回值:NULL 软件定时器创建失败,其他值 软件定时器创建成功,返回其句柄
开启软件定时器 xTimerStart()
BaseType_t xTimerStart(TimerHandle_t xTimer,const TickType_t xTicksToWait)
参数:待开启软件定时器的句柄,发送命令到软件定时器命令队列的等待时间
返回值:pdPASS 开启成功,pdFAIL 开启失败
停止软件定时器 xTimerStop()
BaseType_t xTimerStop(TimerHandle_t xTimer,const TickType_t xTicksToWait);
参数:待停止软件定时器的句柄,发送命令到软件定时器命令队列的等待时间
返回值:pdPASS 停止成功,pdFAIL 停止失败
复位软件定时器 xTimerReset()
BaseType_t xTimerReset(TimerHandle_t xTimer,const TickType_t xTicksToWait);
参数:待复位软件定时器的句柄,发送命令到软件定时器命令队列的等待时间
返回值:pdPASS 复位成功,pdFAIL 复位失败
更改软件定时器的定时超时时间
BaseType_t xTimerChangePeriod(TimerHandle_t xTimer,const TickType_t xNewPeriod,const TickType_t xTicksToWait);
参数:待更改软件定时器的句柄,新的定时超时时间,发送命令到软件定时器命令队列的等待时间
返回值:pdPASS 复位成功,pdFAIL 复位失败
删除软件定时器
BaseType_t xTimerDelete(TimerHandle_t xTimer,const TickType_t xTicksToWait);
参数:待删除软件定时器的句柄,发送命令到软件定时器命令队列的等待时间
返回值:pdPASS 删除成功,pdFAIL 删除失败
//freertos_demo.c
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS******************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
/************************************************************************************/
/*FreeRTOS配置*/
/* START_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);
/* TASK1 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1(void* pv);
void time1_callback(TimerHandle_t pxTimer); //申明单次定时器1
void time2_callback(TimerHandle_t pxTimer); //申明周期定时器2
/***************************************************************************************/
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t ) start_task, //创建开始任务
(char* ) "start_task",
(unsigned portSHORT) START_TASK_STACK_SIZE,
(void * ) NULL,
(portBASE_TYPE ) START_TASK_PRIO,
(TaskHandle_t* ) &start_task_handler );
vTaskStartScheduler();
}
TimerHandle_t timer1_handle = 0; //定义单次定时器
TimerHandle_t timer2_handle = 0; //定义周期定时器
void start_task(void* pvPara)
{
taskENTER_CRITICAL(); //进入临界区
//创建单次定时器
timer1_handle = xTimerCreate( "timer1", 1000,pdFALSE,(void*)1,time1_callback);//定时器名字,超时周期,单次定时器,ID,回调函数
//创建周期定时器
timer2_handle = xTimerCreate( "timer2", 1000,pdTRUE,(void*)2,time2_callback);//定时器名字,超时周期,周期定时器,ID,回调函数
xTaskCreate((TaskFunction_t ) task1, //创建任务一
(char* ) "task1",
(unsigned portSHORT) TASK1_STACK_SIZE,
(void * ) NULL,
(portBASE_TYPE ) TASK1_PRIO,
(TaskHandle_t* ) &task1_handler );
vTaskDelete(NULL); //删除start_task任务
taskEXIT_CRITICAL(); //退出临界区
}
//任务一 按键扫描并控制软件定时器
void task1(void* pv)
{
uint8_t key = 0;
while(1)
{
key = key_scan(0);
if(key == KEY0_PRES)
{
xTimerStart(timer1_handle,portMAX_DELAY); //开启定时器1
xTimerStart(timer2_handle,portMAX_DELAY); //开启定时器2
}else if(key == KEY1_PRES)
{
xTimerStop(timer1_handle,portMAX_DELAY); //暂停定时器1
xTimerStop(timer2_handle,portMAX_DELAY); //暂停定时器2
}
vTaskDelay(10);
}
}
//time1的超时回调函数
void time1_callback(TimerHandle_t pxTimer)
{
static uint32_t timer = 0; //加静态是避免每次进入都初始化一遍
printf("time1的允许次数:%d\r\n",++timer);
}
//time2的超时回调函数
void time2_callback(TimerHandle_t pxTimer) //注意里面不能有延时阻塞函数
{
static uint32_t timer = 0; //加静态是避免每次进入都初始化一遍
printf("time2的允许次数:%d\r\n",++timer);
}