延时函数的分类
相对延时:
vTaskDelay
绝对延时:
vTaskDelayUntil
vTaskDelay
相对延时:
vTaskDelay
函数用于实现相对于当前时间的延时,它会使当前任务挂起(进入阻塞状态)指定的ticks数后再唤醒执行。这里的"ticks"是FreeRTOS中的时间单位,通常与系统滴答定时器相关联。
- 想象一下,你周末早上躺在床上,打算再小憩一会儿。你心里有个大概的想法,比如“我再睡10分钟”。这时候,你不需要看表,也不管现在几点,就是简单地决定从现在开始,再躺10分钟后起床。这就是
vTaskDelay
的工作方式。它让你的任务(在这里,你可以把自己想象成那个任务)从现在开始暂停一段指定的时间(比如10分钟),然后继续执行下一项活动。至于这段时间内外界发生了什么,你并不关心,你只关注自己休息了多久。
函数原型:
void vTaskDelay( TickType_t xTicksToDelay );
- 参数
xTicksToDelay
指定了任务需要延时的ticks数量。例如,如果系统滴答频率是100Hz(即每10ms一个tick),那么xTicksToDelay = 100
意味着延时1秒。
使用场景: 当你需要让当前任务暂停一段时间,但不需要精确控制何时开始下一次执行时,vTaskDelay
非常有用。它适用于简单的定时、循环延时等场景。
vTaskDelayUntil
绝对延时: 相比之下,
vTaskDelayUntil
允许你基于某个绝对时间点来安排任务的唤醒。它接受两个参数:一个是用于保存上次唤醒时间或期望下次唤醒时间的变量,另一个是要延时的ticks数。它计算下一次唤醒时间,并使任务延时到那个时间点。
- 现在,换个场景,假设你是秘书,需要为老板安排一周后的会议提醒。这个提醒必须在特定的时间点触发,比如说下周三下午3点。这时,你不仅要知道从现在开始到那天还有多久,还要确保到了那个确切的时间点,提醒能准时响起。这就像是
vTaskDelayUntil
的功能。它不仅考虑了延时的长度,还考虑了开始计时的参考点,确保任务在预设的准确时刻执行。就像是你设置了一个日历提醒,无论你什么时候设置的,它都会在那个确切的周三下午3点提醒你。
函数原型:
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, TickType_t xTimeIncrement );
- 参数
pxPreviousWakeTime
是一个指向变量的指针,该变量保存了任务上一次唤醒的时间(ticks)。首次调用时,应初始化为xTaskGetTickCount()
的返回值。 - 参数
xTimeIncrement
指定了从上次唤醒到现在或下次希望延时的ticks数。
vTaskDelay
就像是说“等一会儿再说”,它让你的任务在不关心具体时间点的情况下,简单地延迟一段时间后继续。
vTaskDelayUntil
则是安排一个“到点就做”的计划,它确保任务会在一个基于某个特定时间点的未来时刻被唤醒执行。
vTaskDelay 与 HAL_Delay 的区别
- vTaskDelay 作用是让任务阻塞,任务阻塞后,RTOS系统调用其它处于就绪状态的优先级最高的任务来执行。
- HAL_Delay 一直不停的调用获取系统时间的函数,直到指定的时间流逝然后退出,故其占用了全部CPU时间。
软件定时器
什么是定时器?
简单可以理解为闹钟,到达指定一段时间后,就会响铃。
STM32
芯片自带硬件定时器,精度较高,达到定时时间后会触发中断,也可以生成
PWM
、输入
捕获、输出比较,等等,功能强大,但是由于硬件的限制,个数有限。
软件定时器也可以实现定时功能,达到定时时间后可调用回