FreeRTOS教程9 软件定时器

这篇具有很好参考价值的文章主要介绍了FreeRTOS教程9 软件定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、准备材料

正点原子stm32f407探索者开发板V2.4

STM32CubeMX软件(Version 6.10.0)

Keil µVision5 IDE(MDK-Arm)

野火DAP仿真器

XCOM V2.6串口助手

2、学习目标

本文主要学习 FreeRTOS 软件定时器的相关知识,包括软件定时器回调函数、属性、状态、运行原理和常见 API 函数等知识

3、前提知识

3.1、软件定时器回调函数

软件定时器的回调函数是一个返回值为 void 类型,并且只有软件定时器句柄一个参数的 C 语言函数,其函数的具体原型如下所述

/**
  * @brief  软件定时器回调函数
  * @param  xTimer:软件定时器句柄
  * @retval None
  */
void ATimerCallback(TimerHandle_t xTimer)
{
	/* do something */
}

软件定时器回调函数会在定时器设定的时间到期时在 RTOS 守护进程任务中被执行,软件定时器回调函数从头到尾执行,并以正常方式退出

需要读者注意的是软件定时器的回调函数应尽可能简短,并且在该函数体内不能调用任何会使任务进入阻塞状态的 API 函数,但是如果设置调用函数的 xTicksToWait 参数为 0 ,则可以调用如 xQueueReceive() 等 API 函数

3.2、软件定时器属性和状态

3.2.1、周期

这个属性比较好理解,软件定时器的周期指的是 从软件定时器启动到软件定时器回调函数执行之间的时间,该属性是定时器不可或缺的重要属性

3.2.2、分类

软件定时器根据行为的不同分为了 单次定时器(One-shot timers) 和 周期定时器(Auto-reload timers) 两种类型,如下图展示了两种不同类型软件定时器的行为差异 (注释1)

3.2.3、状态

根据定时器是否正在运行可以将定时器分为 运行状态(Running) 和 休眠状态(Dormant) 两种不同状态,如下图所示展示了单次定时器和周期定时器在两种不同状态之间的转换过程

从图上可以看出以下几点内容

  1. 不管是单次定时器还是周期定时器,在定时器创建成功之后都处于休眠状态,一旦调用启动、复位或改变定时器周期的 API 函数就会使定时器从休眠状态转移到运行状态;
  2. 单次定时器定时时间到期之后执行一次回调函数就会自动转换为休眠状态,而周期定时器会一直处于运行状态;
  3. 当对处于运行状态的定时器调用停止 API 函数时,不管是哪种定时器都会转变为休眠状态

定时器的状态可以通过 xTimerlsTimerActive() API 函数查询,该函数具体声明如下所述

/**
  * @brief  查询软件定时器是否处于运行或休眠状态
  * @param  xTimer:要查询的定时器句柄
  * @retval 如果定时器处于休眠状态则返回pdFALSE,如果定时器处于运行状态则返回pdTRUE
  */
BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer);

3.3、软件定时器运行原理

3.3.1、RTOS 守护进程任务

首先读者应该知道的一点是所有软件定时器的回调函数都在同一个 RTOS 守护进程任务的上下文中执行,这个 RTOS 守护进程任务和空闲任务一样,在调度器启动的时候会被自动创建, RTOS 守护进程任务的优先级和堆栈大小分别由 configTIMER_TASK_PRIORITY configTIMER_TASK_STACK_DEPTH 两个参数设置(可在 STM32CubeMX 软件中配置)

”3.1、软件定时器回调函数“ 小节提到在回调函数中不能使用会使任务进入阻塞状态的 API 函数,这是因为调用会使任务进入阻塞状态的 API 函数会使 RTOS 守护进程任务进入阻塞状态,这是不被允许的

3.3.2、定时器命令队列

上面提到的软件定时器的启动、复位、改变定时器周期和停止等操作的 API 函数只是将控制定时器的命令从调用任务发送到称为 “定时器命令队列” 的队列上,然后由 RTOS 守护进程任务从定时器命令队列中取出命令对定时器实际操作

定时器命令队列是 FreeRTOS 里的一个标准队列,其也是在调度程序启动时被自动创建的,定时器命令队列的长度可以由 configTIMER_QUEUE LENGTH 参数设置

如下图所示为软件定时器 API 函数使用定时器命令队列与 RTOS 守护程序任务进行通信的示意图

3.3.3、守护进程任务调度

守护进程任务是一个 FreeRTOS 任务,所以其任务调度会遵循和其他任务一样的调度规则,当守护进程任务是能够运行的最高优先级任务时,它将会处理定时器队列中的命令或执行定时器的回调函数

守护进程任务的优先级在 STM32CubeMX 中默认为 2 ,当守护进程任务的优先级低于调用 xTimerStart() 等 API 函数的任务的优先级时,其会在任务结束之后轮到守护进程任务执行时对 “开始定时器” 命令进行处理,具体如下图所示

当守护进程任务的优先级高于调用 xTimerStart() 等 API 函数的任务的优先级时,一旦任务调用 xTimerStart() 等 API 函数将命令写入定时器命令队列,守护进程任务便可以抢占该任务,立即处理写入定时器命令队列的命令,处理完毕之后进入阻塞状态,处理器返回原任务继续执行,具体如下图所示

3.4、创建、启动软件定时器

同样,根据 FreeRTOS API 的惯例,创建软件定时器仍然提供了动态内存创建和静态内存创建两个不同的 API 函数,软件定时器可以在调度程序运行之前创建,也可以在调度程序启动后从任务创建,如下所示为两个 API 函数声明

/**
  * @brief  动态分配内存创建软件定时器
  * @param  pcTimerName:定时器的描述性名称,辅助调试用
  * @param  xTimerPeriod:定时器的周期,参考 “3.2.1、周期” 小节
  * @param  uxAutoReload:pdTRUE表示周期软件定时器,pdFASLE表示单次软件定时器
  * @param  pvTimerID:定时器ID
  * @param  pxCallbackFunction:定时器回调函数指针,参考 “3.1、软件定时器回调函数” 小节
  * @retval 创建成功则返回创建的定时器的句柄,失败则返回NULL
  */
TimerHandle_t xTimerCreate(const char * const pcTimerName,
						   const TickType_t xTimerPeriod,
						   const UBaseType_t uxAutoReload,
						   void * const pvTimerID,
						   TimerCallbackFunction_t pxCallbackFunction);

/**
  * @brief  动态分配内存创建软件定时器
  * @param  pcTimerName:定时器的描述性名称,辅助调试用
  * @param  xTimerPeriod:定时器的周期,参考 “3.2.1、周期” 小节
  * @param  uxAutoReload:pdTRUE表示周期软件定时器,pdFASLE表示单次软件定时器
  * @param  pvTimerID:定时器ID
  * @param  pxCallbackFunction:定时器回调函数指针,参考 “3.1、软件定时器回调函数” 小节
  * @param  pxTimerBuffer:指向StaticTimer_t类型的变量,然后用该变量保存定时器的状态
  * @retval 创建成功则返回创建的定时器的句柄,失败则返回NULL
  */
TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
								  const TickType_t xTimerPeriod,
								  const UBaseType_t uxAutoReload,
								  void * const pvTimerID,
								  TimerCallbackFunction_t pxCallbackFunction
								  StaticTimer_t *pxTimerBuffer);

创建完的软件定时器处于休眠状态,需要调用启动定时器或其他 API 函数才会进入运行状态,xTimerStart() 可以在调度程序启动之前调用,但是完成此操作后,软件定时器直到调度程序启动的时间才会真正启动,启动定时器的 API 函数如下所述

/**
  * @brief  启动定时器
  * @param  xTimer:要操作的定时器句柄
  * @param  xBlockTime:参考 “3.4.1、xTicksToWait 参数” 小节
  * @retval 参考 “3.4.2、函数返回值” 小节
  */
BaseType_t xTimerStart(TimerHandle_t xTimer,
					   TickType_t xTicksToWait);

/**
  * @brief  启动定时器的中断安全版本
  * @param  xTimer:要操作的定时器句柄
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval 参考 “3.4.2、函数返回值” 小节
  */
BaseType_t xTimerStartFromISR(TimerHandle_t xTimer,
							  BaseType_t *pxHigherPriorityTaskWoken);

3.4.1、xTicksToWait 参数

xTimerStart() 使用定时器命令队列向守护进程任务发送 “启动定时器” 命令, xTicksToWait 指定调用任务应保持在阻塞状态以等待定时器命令队列上的空间变得可用的最长时间(如果队列已满),该参数需要注意以下几点

  1. 如果 xTicksToWait 为零且定时器命令队列已满,xTimerStart() 将立即返回,该参数以滴答定时器时间刻度为单位,可以使用宏 pdMS_TO_TICKS() 将以毫秒为单位的时间转换为以刻度为单位的时间,例如 pdMS_TO_TICKS(50) 表示阻塞 50ms

  2. 如果在 FreeRTOSConfig.h 中将 INCLUDE_vTaskSuspend 设置为 1,则将 xTicksToWait 设置为 portMAX_DELAY 将导致调用任务无限期地保持在阻塞状态(没有超时),以等待定时器命令队列中的空间变得可用

  3. 如果在启动调度程序之前调用 xTimerStart(),则 xTicksToWait 的值将被忽略,并且 xTimerStart() 的行为就像 xTicksToWait 已设置为零一样

3.4.2、xTimerStart() 函数返回值

有两种可能的返回值,分别为 pdPASS 和 pdFALSE ,具体如下所述

① 仅当 “启动定时器” 命令成功发送到定时器命令队列时,才会返回 pdPASS

  1. 如果守护程序任务的优先级高于调用 xTimerStart() 的任务的优先级,则调度程序将确保在 xTimerStart() 返回之前处理启动命令。这是因为一旦定时器命令队列中有数据,守护任务就会抢占调用 xTimerStart() 的任务,从而总是保证将命令成功发送到定时器命令队列
  2. 如果指定了阻塞时间(xTicksToWait 不为零),则调用任务可能会被置于阻塞状态,以等待定时器命令队列中的空间在函数返回之前变得可用,只要在阻塞时间到期之前命令已成功写入定时器命令队列,就可以返回 pdPASS

② 如果由于队列已满或超过阻塞时间等原因无法将 “启动定时器” 命令写入定时器命令队列,则将返回 pdFALSE

  1. 如果指定了阻塞时间(xTicksToWait 不为零),则调用任务将被置于阻塞状态以等待守护进程任务在定时器命令队列中腾出空间,但是指定的阻塞时间在等待定时器命令队列中腾出空间之前已过期,所以返回 pdFALSE

3.6、软件定时器 ID

每个软件定时器都有一个 ID ,它是一个标签值,应用程序编写者可以将其用于任何目的, ID 被存储在空指针中,因此可以直接存储整数值,指向任何其他对象,或用作函数指针

创建软件定时器时会为 ID 分配一个初始值,之后可以使用 vTimerSetTimerID() API 函数更新 ID,并且可以使用 pvTimerGetTimerID() API 函数查询 ID ,这两个 API 函数具体如下所示

/**
  * @brief  设置定时器ID值
  * @param  xTimer:要操作的定时器句柄
  * @param  pvNewID:想要设置软件定时器的新ID值
  * @retval None
  */
void vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID);

/**
  * @brief  获取定时器ID值
  * @param  xTimer:要操作的定时器句柄
  * @retval 正在查询的软件定时器ID
  */
void *pvTimerGetTimerID(TimerHandle_t xTimer);

注意:与其他软件定时器 API 函数不同,vTimerSetTimerID() 和 pvTimerGetTimerID() 直接访问软件定时器,它们不向定时器命令队列发送命令

如果创建了多个软件定时器,并且所有软件定时器均使用了同一个回调函数,则可以给软件定时器设置不同的 ID 值,然后在回调函数中通过 ID 值判断软件定时器触发的来源

3.7、改变软件定时器周期

创建软件定时器时就会为定时器周期设置初始值,后续也可以使用 xTimerChangePeriod() 函数动态更改软件定时器的周期,该函数具体声明如下所示

/**
  * @brief  改变软件定时器的周期
  * @param  xTimer:要操作的定时器句柄
  * @param  xNewPeriod:软件定时器的新周期,以刻度为单位指定
  * @param  xBlockTime:参考 “3.4.1、xTicksToWait 参数” 小节
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
 BaseType_t xTimerChangePeriod(TimerHandle_t xTimer,
							   TickType_t xNewPeriod,
							   TickType_t xBlockTime);

/**
  * @brief  改变软件定时器周期的中断安全版本
  * @param  xTimer:要操作的定时器句柄
  * @param  xNewPeriod:软件定时器的新周期,以刻度为单位指定
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
 BaseType_t xTimerChangePeriodFromISR(TimerHandle_t xTimer,
									  TickType_t xNewPeriod,
									  BaseType_t *pxHigherPriorityTaskWoken);

如果 xTimerChangePeriod() 用于更改已运行的定时器的周期,则定时器将使用新的周期值重新计算其到期时间,重新计算的到期时间是相对于调用 xTimerChangePeriod() 的时间,而不是相对于定时器最初启动的时间

如果使用 xTimerChangePeriod() 更改处于休眠状态(未运行的定时器)的定时器的周期,则定时器将计算到期时间,并转换到运行状态(定时器将开始运行)

另外如果希望查询一个定时器的定时周期,可以通过 xTimerGetPeriod() API 函数查询,具体函数声明如下所述

/**
  * @brief  查询一个软件定时器的周期
  * @param  xTimer:要查询的定时器句柄
  * @retval 返回一个软件定时器的周期
  */
TickType_t xTimerGetPeriod(TimerHandle_t xTimer);

3.8、重置软件定时器

重置软件定时器是指重新启动定时器,定时器的到期时间将根据重置定时器的时间重新计算,而不是相对于定时器最初启动的时间,如下图对此进行了演示,其中显示了一个定时器,该定时器启动的周期为 6,然后重置两次,最后到期并执行其回调函数

FreeRTOS中使用 xTimerReset() API 函数重置软件定时器,除此之外还可用于启动处于休眠状态的定时,该函数具体声明如下所述

/**
  * @brief  重置软件定时器
  * @param  xTimer:要操作的定时器句柄
  * @param  xBlockTime:参考 “3.4.1、xTicksToWait 参数” 小节
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
BaseType_t xTimerReset(TimerHandle_t xTimer,
					   TickType_t xBlockTime);

/**
  * @brief  重置软件定时器的中断安全版本
  * @param  xTimer:要操作的定时器句柄
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
BaseType_t xTimerResetFromISR(TimerHandle_t xTimer,
							  BaseType_t *pxHigherPriorityTaskWoken);

3.8、停止、删除软件定时器

/**
  * @brief  停止软件定时器
  * @param  xTimer:要操作的定时器句柄
  * @param  xBlockTime:参考 “3.4.1、xTicksToWait 参数” 小节
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
BaseType_t xTimerStop(TimerHandle_t xTimer,
					  TickType_t xBlockTime);

/**
  * @brief  删除软件定时器
  * @param  xTimer:要操作的定时器句柄
  * @param  xBlockTime:参考 “3.4.1、xTicksToWait 参数” 小节
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
BaseType_t xTimerDelete(TimerHandle_t xTimer,
						TickType_t xBlockTime);

/**
  * @brief  停止软件定时器的中断安全版本
  * @param  xTimer:要操作的定时器句柄
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval 参考 “3.4.2、xTimerStart() 函数返回值” 小节
  */
BaseType_t xTimerStopFromISR(TimerHandle_t xTimer,
							 BaseType_t *pxHigherPriorityTaskWoken);

3.9、其他 API 函数

/**
  * @brief  将软件定时器的“模式”更新为 自动重新加载定时器 或 一次性定时器 
  * @param  xTimer:要操作的定时器句柄
  * @param  uxAutoReload:设置为pdTRUE则将定时器设置为周期软件定时器,设置为pdFASLE则将定时器设置为单次软件定时器
  * @retval None
  */
void vTimerSetReloadMode(TimerHandle_t xTimer,
						 const UBaseType_t uxAutoReload);

/**
  * @brief  查询软件定时器是 单次定时器 还是 周期定时器
  * @param  xTimer:要查询的定时器句柄
  * @retval 如果为周期软件定时器则返回pdTRUE,否则返回pdFALSE
  */
BaseType_t xTimerGetReloadMode(TimerHandle_t xTimer);

/**
  * @brief  查询软件定时器到期的时间
  * @param  xTimer:要查询的定时器句柄
  * @retval 如果要查询的定时器处于活动状态则返回定时器下一次到期的时间,否则未定义返回值
  */
TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer);

4、实验一:软件定时器的应用

4.1、实验目标

  1. 创建一个周期软件定时器 TimerPeriodic 和一个单次软件定时器 TimerOnce
  2. 创建一个按键扫描任务 Task_KeyScan,根据不同按键实现不同响应
  3. 当按键 WK_UP 按下时,设置周期定时器以 500ms 周期执行;当按键 KEY2 按下时,设置单次定时器以 1s 周期执行一次;当按键 KEY1 按下时,对周期定时器进行复位操作;当按键 KEY0 按下时,停止 TimerPeriodic 周期定时器

4.2、CubeMX相关配置

首先读者应按照 "FreeRTOS教程1 基础知识" 章节配置一个可以正常编译通过的 FreeRTOS 空工程,然后在此空工程的基础上增加本实验所提出的要求

本实验需要初始化 USART1 作为输出信息渠道,具体配置步骤请阅读“STM32CubeMX教程9 USART/UART 异步通信”,如下图所示

本实验需要初始化开发板上 WK_UP、KEY2、KEY1 和 KEY0 用户按键做普通输入,具体配置步骤请阅读“STM32CubeMX教程3 GPIO输入 - 按键响应”,注意虽开发板不同但配置原理一致,如下图所示

单击 Middleware and Software Packs/FREERTOS ,在 Configuration 中单击 Tasks and Queues 选项卡,双击默认任务修改其参数,如下所示

单击 Timers and Semaphores ,在 Timers 中创建周期、单次两个软件定时器,如下所示

配置 Clock Configuration 和 Project Manager 两个页面,接下来直接单击 GENERATE CODE 按钮生成工程代码即可

4.3、添加其他必要代码

按照 “STM32CubeMX教程9 USART/UART 异步通信” 实验 “6、串口printf重定向” 小节增加串口 printf 重定向代码,具体不再赘述

首先应该在 freertos.c 中添加软件定时器的头文件和使用到的 printf 的头文件,如下所述

#include "timers.h"
#include "stdio.h"

然后实现按键扫描任务函数体,当按键 WK_UP 按下时启动周期软件定时器,当按键 KEY2 按下时启动单次软件定时器,当按键 KEY1 按下时对周期软件定时器进行复位操作,当按键 KEY0 按下时停止周期定时器,具体如下所述

void AppTask_KeyScan(void *argument)
{
	/* USER CODE BEGIN AppTask_KeyScan */
	uint8_t key_value = 0;
	/* Infinite loop */
	for(;;)
	{
		key_value = 0;
		//按键WK_UP按下
		if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET)
			key_value = 4;
		//按键KEY2按下
		if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET)
			key_value = 3;
		//按键KEY1按下
		if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET)
			key_value = 2;
		//按键KEY0按下
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET)
			key_value = 1;
		
		if(key_value != 0)
		{
			if(key_value == 4)
			{
				if(xTimerChangePeriod(TimerPeriodicHandle, 500, pdMS_TO_TICKS(500)) == pdTRUE)
				{
					printf("\r\nWK_UP PRESSED, TimerPeriodic Start!\r\n\r\n");
				}
			}
			if(key_value == 3)
			{
				if(xTimerChangePeriod(TimerOnceHandle, 1000, pdMS_TO_TICKS(500)) == pdTRUE)
				{
					printf("\r\nKEY2 PRESSED, TimerOnce Start!\r\n\r\n");
				}
			}
			else if(key_value == 2)
			{
				if(xTimerReset(TimerPeriodicHandle, pdMS_TO_TICKS(500)) == pdTRUE)
				{
					printf("\r\nKEY1 PRESSED, TimerPeriodic Reset!\r\n\r\n");
				}
			}
			else if(key_value == 1)
			{
				if(xTimerStop(TimerPeriodicHandle, pdMS_TO_TICKS(500)) == pdTRUE)
				{
					printf("\r\nKEY0 PRESSED, TimerPeriod Stop!\r\n\r\n");
				}
			}
			//有按键按下就进行按键消抖
			osDelay(300);
		}
		else
			osDelay(10);
	}
	/* USER CODE END AppTask_KeyScan */
}

最后实现单次/周期软件定时器的两个回调函数即可,回调函数内不做任何具体操作,仅通过串口输出提示信息,如下所述

/* appTimerPeriodic function */
void appTimerPeriodic(void *argument)
{
  /* USER CODE BEGIN appTimerPeriodic */
	printf("Into appTimerPeriodic Function\r\n");
  /* USER CODE END appTimerPeriodic */
}

/* appTimerOnce function */
void appTimerOnce(void *argument)
{
  /* USER CODE BEGIN appTimerOnce */
	printf("Into appTimerOnce Function\r\n");
  /* USER CODE END appTimerOnce */
}

4.4、烧录验证

烧录程序,打开串口助手后无任何信息输出,当按下开发板上的 WK_UP 按键之后,会启动以 500ms 为周期的周期软件定时器,此时周期软件定时器的回调函数会周期得到执行;当按下开发板上的 KEY2 按键之后,会启动 1s 为周期的单次软件定时器,此时单次软件定时器的回调函数会得到执行,并且只执行了一次就停止了执行;当按下开发板上的 KEY1 按键时,会复位周期定时器;当按下开发板上的 KEY0 按键时,会停止周期定时器,整个过程串口的输出信息如下图所示

5、注释详解

注释1:图片来源于 Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf

参考资料

STM32Cube高效开发教程(基础篇)

Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf文章来源地址https://www.toymoban.com/news/detail-841972.html

到了这里,关于FreeRTOS教程9 软件定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (第48-59讲)STM32F4单片机,FreeRTOS【事件标志、任务通知、软件定时器、Tickless低功耗】【纯文字讲解】【】

    【吐血总结】FreeRTOS难点、Systick中断-滴答定时器、PendSV中断-任务切换、SVC中断-系统底层、时间片调度-时钟节拍【已完结】 (第1-8讲)STM32F4单片机,FreeRTOS基础知识总结【视频笔记、代码讲解】【正点原子】【原创】 (第9-10讲)STM32F4单片机,FreeRTOS任务创建和删除(动态方

    2024年02月01日
    浏览(54)
  • 【STM32/FreeRTOS】SysTick定时器及FreeRTOS系统节拍

    目录 一、SysTick定时器 1、SysTick寄存器介绍 (1)控制及状态寄存器 (2)重装载数值寄存器 (3)当前数值寄存器 2、SysTick寄存器配置函数 二、FreeRTOS中的SysTick定时器 1、SysTick配置函数及分析 2、SysTick中断函数 三、其他操作配置FreeRTOS的SysTick 1、找到头文件 FreeRTOSConfig.h 有如

    2024年01月24日
    浏览(35)
  • STM32软件定时器

    目录 什么是定时器? 软件定时器优缺点 软件定时器原理 软件定时器相关配置 单次定时器和周期定时器 软件定时器相关 API 函数 1. 创建软件定时器 2. 开启软件定时器 3. 停止软件定时器 4. 复位软件定时器 5. 更改软件定时器定时时间 实操 cubeMX配置 代码实现  简单可以理解为

    2024年02月11日
    浏览(29)
  • 【杰理AC696X】软件定时器介绍

    测试SDK版本:《ac696n_soundbox_sdk_v1.6.0》 SDK给出了软件定时器的相关接口,主要有 sys_hi_timer_add、sys_s_hi_timer_add、sys_timer_add等。 列出AC696X系列软件定时器的相关知识点,再结合代码调试和工具测试,总结出使用案例。 上面的低功耗指的是 power down,不是soft poweroff。 usr_timer的强

    2024年02月10日
    浏览(34)
  • 9.物联网操作系统之软件定时器

    一。软件定时器概念及应用 1.软件定时器定义         就是软件实现定时器。 2.FreeRTOS软件定时器介绍         如上图所示,Times的左边为设置定时器时间,设置方式可以为任务设置或者中断设置;Times的右边为定时器的定时响应,使用CallBack响应。  3.FreeRTOS软件定时器工作

    2024年02月14日
    浏览(36)
  • STM32CubeMX教程5 TIM 定时器概述及基本定时器

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 逻辑分析仪nanoDLA 使用STM32CubeMX软件配置STM32F407开发板 使用基本定时器TIM6实现每500ms控制绿灯状态变化一次,基本定时器TIM7实现每1s控制红灯状态变化一次 STM32F407拥有2个基础定时器、

    2024年02月03日
    浏览(79)
  • 物联网操作系统-软件定时器(software timer)

    软件定时器就是\\\"闹钟\\\",你可以设置闹钟, ⚫ 在 30 分钟后让你起床工作 ⚫ 每隔 1 小时让你例行检查机器运行情况 软件定时器也可以完成两类事情: ⚫ 在\\\"未来\\\"某个时间点,运行函数 ⚫ 周期性地运行函数 日常生活中我们可以定无数个\\\"闹钟\\\",这无数的\\\"闹钟\\\"要基于一个真实

    2024年02月21日
    浏览(37)
  • 9.物联网操作系统之软件定时器,实现一个闹钟

    一。软件定时器概念及应用 1.软件定时器定义         就是软件实现定时器。 2.FreeRTOS软件定时器介绍         如上图所示,Times的左边为设置定时器时间,设置方式可以为任务设置或者中断设置;Times的右边为定时器的定时响应,使用CallBack响应。  3.FreeRTOS软件定时器工作

    2024年02月12日
    浏览(38)
  • 鸿蒙Hi3861学习六-Huawei LiteOS(软件定时器)

            软件定时器,是 基于系统Tick时钟中断 且由 软件来模拟的定时器 。当经过设定的Tick时钟计数值后,会 触发用户定义的回调函数 。定时精度与系统Tick时钟周期有关。         硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此,为了满足用户需求,

    2024年02月03日
    浏览(34)
  • 学习笔记|定时器|STC中断|定时器时间计算|STC32G单片机视频开发教程(冲哥)|第十一集:定时器的作用和意义

    什么是定时器:定时器-与非网 上节课的一段代码: TimeCount++然后一个延时1毫秒,每运行1ms,变量就会加一。 系统已经运行了多少个毫秒。 实际使用时的代码如下, 判断按键有沿有按下的时候,我们等待按键松开,还有一个while循环。 如果没有松开,会一直死在这一行。所以,

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包