FreeRTOS——软件定时器知识总结及其实战

1.软件定时器概念

是指具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息。

2 软件定时器使用特点

1)如果要使能软件定时器,需将configUSE_TIMERS 配置项配置成 1
2)软件定时器支持设置成:单次定时器或周期定时器
3)软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的 API 函数。

3 软件定时器服务任务

在调用函数 vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。
其作用:
1、负责软件定时器超时的逻辑判断
2、调用超时软件定时器的超时回调函数
3、处理软件定时器命令队列
在这里插入图片描述

4软件定时器相关配置

1)当FreeRTOS 的配置项 configUSE_TIMERS 设置为1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask( ) ;
2)软件定时器服务任务的优先级为 configTIMER_TASK_PRIORITY = 31;
3)定时器的命令队列长度为 configTIMER_QUEUE_LENGTH = 5 ;

注意事项:软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务的,它还要处理其他定时器。因此调用的回调函数不能被阻塞,要求如下:
1、回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的 API 函数,如:vTaskDelay()
2、访问队列或者信号量的非零阻塞时间的 API 函数也不能调用。

5软件定时器的状态

休眠态:当指定时间到达之后,但因为没有运行,所以其定时超时回调函数不会被执行。
运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用。

注意:
刚创建的软件定时器处于休眠态

6 软件定时器的状态转换

在这里插入图片描述

7 软件定时器结构体

typedef    struct{const char * 					pcTimerName		 /* 软件定时器名字 */ListItem_t 					xTimerListItem		 /* 软件定时器列表项 */TickType_t 					xTimerPeriodInTicks;        	/* 软件定时器的周期 */     void * 						pvTimerID			 /* 软件定时器的ID */TimerCallbackFunction_t	 		pxCallbackFunction; 	/* 软件定时器的回调函数 */#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t 					uxTimerNumber		/*  软件定时器的编号,调试用  */#endifuint8_t 						ucStatus;                     		/*  软件定时器的状态  */} xTIMER;

8软件定时器API函数

在这里插入图片描述
1)创建软件定时器

TimerHandle_t   xTimerCreate(    const char * const   pcTimerName,				const TickType_t 	  xTimerPeriodInTicks,				const UBaseType_t 	    uxAutoReload,					void * const 			    pvTimerID,				TimerCallbackFunction_t     pxCallbackFunction  ); 

形参:
pcTimerName :软件定时器名
xTimerPeriodInTicks:定时超时时间,单位:系统时钟节拍
uxAutoReload:定时器模式, pdTRUE:周期定时器, pdFALSE:单次定时器
pvTimerID:软件定时器 ID,用于多个软件定时器公用一个超时回调函数
pxCallbackFunction:软件定时器超时回调函数
返回值:
NULL 创建失败
其他 返回句柄,创建成功

2)开启软件定时器

BaseType_t   xTimerStart( 	TimerHandle_t 	xTimer,			const TickType_t 	xTicksToWait  ); 

形参:
xTimer: 等待软件定时器句柄
xTicksToWait:发送命令到软件定时器命令队列的最大等待时间
返回值:
pdPASS 成功
pdFAIL 失败

3)停止软件定时器API函数

BaseType_t   xTimerStop(  TimerHandle_t 	xTimer,			const TickType_t 	xTicksToWait);

形参:
xTimer: 软件定时器句柄
xTicksToWait:发送命令到软件定时器命令队列的最大等待时间
返回值:
pdPASS 成功
pdFAIL 失败

4)复位软件定时器

BaseType_t  xTimerReset( TimerHandle_t 	xTimer,				const TickType_t 	xTicksToWait);

形参:
xTimer: 软件定时器句柄
xTicksToWait:发送命令到软件定时器命令队列的最大等待时间
返回值:
pdPASS 成功
pdFAIL 失败
注意:该功能将使软件定时器的重新开启定时,复位后的软件定时器以复位时的时刻作为开启时刻重新定时

5)更改软件定时器超时时间

BaseType_t  xTimerChangePeriod( TimerHandle_t 		xTimer,	const TickType_t 	xNewPeriod, const TickType_t 	xTicksToWait); 				                                                                                              	          

形参:
xTimer: 软件定时器句柄
xNewPeriod: 新的定时超时时间,单位:系统时钟节拍
xTicksToWait:发送命令到软件定时器命令队列的最大等待时间
返回值:
pdPASS 成功
pdFAIL 失败

8软件定时器实战

在这里插入图片描述
代码:

#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 *//* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task1Task_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 *///定义定时器回调函数、与定时器句柄
TimerHandle_t timer1_handle = 0;        //单次定时器
TimerHandle_t timer2_handle = 0;        //周期定时器void timer1_callback(TimerHandle_t pxTimer);
void timer2_callback(TimerHandle_t pxTimer);/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */(const char*    )"start_task",          /* 任务名称 */(uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */(void*          )NULL,                  /* 传入给任务函数的参数 */(UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */(TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */vTaskStartScheduler();
}/*** @brief       start_task* @param       pvParameters : 传入参数(未用到)* @retval      无*/
void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */// 定时器1创建为单次定时器 timer1_handle = xTimerCreate("timer1", 500, pdFALSE, (void *)1, timer1_callback);// 定时器2创建为周期定时器 timer2_handle = xTimerCreate( "timer2", 2000,pdTRUE, (void*)2, timer2_callback);xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &Task1Task_Handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/*** @brief       task1* @param       pvParameters : 传入参数(未用到)* @retval      无*/
//任务一、按键扫描并控制软件定时器
void task1(void *pvParameters)
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY0_PRES){xTimerStart(timer1_handle,portMAX_DELAY);xTimerStart(timer2_handle,portMAX_DELAY);}else if(key == KEY1_PRES){xTimerStop(timer1_handle,portMAX_DELAY);xTimerStop(timer2_handle,portMAX_DELAY);}vTaskDelay(10);}
}/*** @brief       Timer1超时回调函数* @param       xTimer : 传入参数(未用到)* @retval      无*/
//timer1的超时回调函数
void timer1_callback(TimerHandle_t pxTimer)
{static uint32_t timer = 0;printf("timer1的运行次数:%d\r\n",++timer);
}/*** @brief       Timer2超时回调函数* @param       xTimer : 传入参数(未用到)* @retval      无*/
void timer2_callback(TimerHandle_t pxTimer)
{static uint32_t timer = 0;printf("timer2的运行次数:%d\r\n",++timer);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/322918.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防浪涌TVS:电子设备的保护盾?|深圳比创达电子

在电子设备日益普及的今天,我们经常会听到设备因电压波动或突发浪涌而损坏的情况。那么,有没有一种方式可以保护我们的设备免受这些意外伤害?答案就是“防浪涌TVS(Transient Voltage Suppressor)”。但它是什么?它如何工作&#x…

推荐一款加速器,也可加速github

地址https://github.com/BeyondDimension/SteamTools

docker 部署haproxy cpu占用特别高

在部署mysql 主主高可用时&#xff0c;使用haproxy进行负载&#xff0c;在服务部使用的情况下发现服务器cpu占比高&#xff0c;负载也高&#xff0c;因此急需解决这个问题。 1.解决前现状 1.1 部署配置文件 cat > haproxy.cfg << EOF globalmaxconn 4000nbthrea…

小白入门基础 - spring Boot 入门

1.简介 spring Boot是为了简化java的开发流程而构建的&#xff0c;即使是使用springMVC框架&#xff0c;也依然需要大量配置和依赖导入&#xff0c; 这无疑是繁琐的&#xff0c;spring Boot采用了”习惯由于配置“的原则&#xff0c;进行一键化部署&#xff0c;这样极大…

HTTP基础知识总结

目录 一、什么是HTTP&#xff1f; 二、与HTTP有关的协议 三、HTTP请求特征 四、HTTP组成格式 五、HTTP标头 1.通用标头 2.实体标头 3.请求标头 4.响应标头 六、HTTP状态码分类 我们在日常测试过程中&#xff0c;也可以通过浏览器F12简单定位是前端问题还是后端问题&a…

Android kotlin build.gradle.kts配置

1. 添加 maven 仓库 1. 1. settings配置 1. 1.1. settings.gradle repositories {maven {url https://maven.aliyun.com/repository/public/}mavenCentral() }1. 1.2. settings.gradle.kts repositories {maven {setUrl("https://maven.aliyun.com/repository/public/…

Linux中 /etc/sysconfig/network-scripts/ifcfg-<interface> 网络接口配置 详解 看这一篇够用

CSDN 成就一亿技术人&#xff01; 今天就来讲讲Linux中的网络配置详解 CSDN 成就一亿技术人&#xff01; 在 Linux 系统中&#xff0c;/etc/sysconfig/network-scripts 目录包含用于配置网络接口的脚本和配置文件。这些文件由 NetworkManager 服务使用来启动、停止和管理网络…

python入门,list列表详解

目录 1.list的定义 2.index查找某元素的下标 3.修改 ​编辑 4.插入 ​编辑 5.追加元素 1.append,追加到尾部 2.extend,追加一批元素 ​编辑 6.删除元素 1.del 列表[下标] 2.列表.pop(下标) 3.列表.remove(元素) 7.清空列表 8.统计某一元素在列表内的数量 9.计算…

【后端已完成,前端更新ing】uniapp+springboot实现个人备忘录系统【前后端分离】

目录 &#xff08;1&#xff09;项目可行性分析 &#xff08;一&#xff09;技术可行性&#xff1a; &#xff08;二&#xff09;经济可行性&#xff1a; &#xff08;三&#xff09;社会可行性&#xff1a; &#xff08;2&#xff09;需求描述 功能模块图 用例图&#…

基于卷积神经网络的回归分析

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络的回归分析 完整代码:卷积神经网络的回归分析(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/…

银河麒麟Kylin-Server-V10-SP3使用ISO镜像搭建本地内网YUM/DNF源cdrom/http

机房服务器安装一般是内网环境&#xff0c;需要配置本地的YUM/DNF源。本文介绍通过ISO镜像搭建内网环境的UM/DNF源 准备工作&#xff1a; 提前准备好Kylin-Server-V10-SP3的ISO镜像文件。 本机IP地址&#xff1a;192.168.40.201 镜像存放目录/data/iso/Kylin-Server-V10-SP3-Ge…

UE相关杂项笔记

1.PAK包解析 UE4如何反向查找Pak里面包含哪些文件 - 哔哩哔哩 CMD控制台命令输入 D:&quot;Epic Games&quot;\UE_5.1\Engine\Binaries\Win64\UnrealPak.exe 包路径 -list *文件夹带空格时 添加“ ”包裹住文件夹名 解包工具路径 UE引擎安装路径\UE_5.1\Engine\Binarie…