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

文章介绍了FreeRTOS中的软件定时器功能,包括其基础设置、使用方法和相关函数。通过示例代码展示了如何创建、启动和管理定时器,并强调了回调函数不应在执行中阻塞。软件定时器虽不如硬件定时器精确,但在多数应用中已足够,并且可以创建多个。
摘要由CSDN通过智能技术生成

目的

软件定时器是一个非常常用且非常好用的功能,这篇文章将对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 );

总结

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值