FreeRTOS入门(08):软件定时器

Posted Naisu Xu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FreeRTOS入门(08):软件定时器相关的知识,希望对你有一定的参考价值。

文章目录

目的

软件定时器是一个非常常用且非常好用的功能,这篇文章将对FreeRTOS中相关内容做个介绍。

本文代码测试环境见前面的文章:《FreeRTOS入门(01):基础说明与使用演示》

基础说明

软件定时器和基本的硬件定时器有点像,功能比较单一,就是设定一个时间,经过该时间后执行某个回调函数。这个功能看似简单,但是实际开发中还是非常常用的。

使用软件定时器前需要在 FreeRTOSConfig.h 文件中进行下面设置:

/* Software timer definitions. */
// 设置为1来使用软件定时器
#define configUSE_TIMERS				1
// 设置软件定时器后台服务程序(其实就是个任务,在这个场景下下也被叫做守护进程)优先级
#define configTIMER_TASK_PRIORITY		( configMAX_PRIORITIES - 1 )
// 设置软件定时器命令队列长度
#define configTIMER_QUEUE_LENGTH		4
// 设置软件定时器任务栈大小
#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE )

软件定时器使用时需要注意的是和硬件定时器一样回调函数(中断函数)中执行的任务不要阻塞。

使用演示

#include "debug.h"
#include "FreeRTOS.h" // 引入头文件
#include "task.h"     // 引入头文件
#include "timers.h"   // 引入头文件

TimerHandle_t xTimer1; // 定时器句柄
TimerHandle_t xTimer2; // 定时器句柄

// 定时器回调函数
void timer1(TimerHandle_t xTimer) 
    printf("%u timer 1: %s\\r\\n", xTaskGetTickCount(), pvTimerGetTimerID(xTimer));


// 定时器回调函数
void timer2(TimerHandle_t xTimer) 
    printf("%u timer 2: %s\\r\\n", xTaskGetTickCount(), pvTimerGetTimerID(xTimer));


int main(void) 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);

    xTimer1 = xTimerCreate("timer1", 500, pdTRUE, "t1", timer1); // 创建并设置定时器周期执行
    xTimer2 = xTimerCreate("timer2", 1000, pdFALSE, "t2", timer2); // 创建并设置定时器单次执行

    xTimerStart(xTimer1, 0); // 启动定时器
    xTimerStart(xTimer2, 0); // 启动定时器

    vTaskStartScheduler(); // 任务调度,任务将在这里根据情况开始运行,程序将在这里无序循环

    while(1)  // 程序不会运行到这里

相关函数

// 创建软件定时器
// pcTimerName 分配给定时器的可读文本名称
// xTimerPeriod 定时周期,以tick为单位
// uxAutoReload 如果该值为pdTRUE,则定时器会重复执行;如果为pdFALSE,则执行一次后休眠
// pvTimerID 回调函数可以使用此参数, 比如分辨是哪个定时器或者使用set/get函数来保存使用一个值
// pxCallbackFunction 定时时间到之后执行的回调函数,函数原型如下
// typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer )
TimerHandle_t xTimerCreate( const char * const pcTimerName,
                            const TickType_t xTimerPeriod,
                            const UBaseType_t uxAutoReload,
                            void * const pvTimerID,
                            TimerCallbackFunction_t pxCallbackFunction );

// 删除软件定时器
BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xBlockTime );

// 启动软件定时器
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xBlockTime );
BaseType_t xTimerStartFromISR ( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken );
// 停止软件定时器
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xBlockTime );
BaseType_t xTimerStopFromISR ( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken );
// 重置软件定时器
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xBlockTime );
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken );
// 查询软件定时器是否处于活动状态
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );

// 获取定时器周期
TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
// 改变软件定时器周期
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xBlockTime );
BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken );
// 设置与返回定时器是否自动重置
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload );
BaseType_t  xTimerGetReloadMode( TimerHandle_t xTimer );

// 获取与修改ID
void *pvTimerGetTimerID( TimerHandle_t xTimer );
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );

// 获取定时器可读文本名称
const char * pcTimerGetName( TimerHandle_t xTimer );

// 返回定时器下一次触发时间
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );

// 获得软件定时器守护进程句柄
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );

总结

软件定时器使用比较简单,但非常好用,虽然没有硬件的基本定时器来的精确,但是一般使用是足够了,还可以创建非常多个(毕竟只受内存限制)。

以上是关于FreeRTOS入门(08):软件定时器的主要内容,如果未能解决你的问题,请参考以下文章

STM32CubeMX学习笔记(33)——FreeRTOS实时操作系统使用(软件定时器)

FreeRTOS 定时器组

RT-Thread和Freertos的区别?

freeRTOS的软件定时器介绍和使用

STM32CubeIDE+FreeRTOS软件定时器实验

CubeMX使用FreeRTOS编程指南