#define Task_Tick() HAL_GetTick() //HAL_GetTick() 返回自启动以来经过的毫秒数
//“\” 表示此行没有结束
#define Task_Begin(tdelay) static uint32_t TickPrv = 0; \
if((Task_Tick() - TickPrv) >= tdelay) \
{ \
TickPrv = Task_Tick();
#define Task_End() }
其中
#define Task_Begin(tdelay) static uint32_t TickPrv = 0; \
if((Task_Tick() - TickPrv) >= tdelay) \
{ \
TickPrv = Task_Tick();
-
作用:定义一个任务的开始,并检查是否达到设定的执行间隔。
-
参数:
tdelay
(任务执行的间隔时间,单位取决于Task_Tick()
的基准)。 -
内部逻辑:
-
static uint32_t TickPrv = 0;
定义一个静态变量TickPrv
,用于记录任务上一次执行的时间点(初始值为 0)。 -
if((Task_Tick() - TickPrv) >= tdelay)
检查当前时间Task_Tick()
与上一次执行时间TickPrv
的差值是否超过设定的间隔tdelay
。 -
TickPrv = Task_Tick();
如果满足条件,更新TickPrv
为当前时间,并执行后续代码(直到Task_End()
)。#define Task_End() }
-
作用:标记任务的结束,闭合
Task_Begin
中的if
语句块。 -
使用范例:
void MyTask(void) { Task_Begin(1000); // 每隔 1000 个 tick 执行一次 // 这里可以写任务的具体逻辑 Task_End(); }
关键点
-
Task_Tick()
-
需要用户自行实现,通常是一个返回系统运行 tick 计数的函数(如
HAL_GetTick()
、xTaskGetTickCount()
等)。 -
单位可以是毫秒、秒,或其他时间基准,需与
tdelay
匹配。
-
-
static
变量-
TickPrv
是静态变量,生命周期贯穿整个程序运行,确保每次调用都能记住上一次的执行时间。
-
-
适用场景
-
适用于裸机编程(无 RTOS)的简单任务调度。
-
-
注意事项
-
任务不能阻塞(如长时间
while
循环),否则会影响其他任务的调度。 -
适用于非抢占式(协作式)任务管理。
-
-
注意:
HAL_GetTick()
和 HAL_RTC_GetTimeCounter(&hrtc)
是 STM32 HAL 库中两个不同的时间获取函数,它们的底层来源、精度、用途有显著区别。以下是详细对比:
关键区别对比
特性 | HAL_GetTick() | HAL_RTC_GetTimeCounter() |
---|---|---|
底层硬件 | SysTick(内核定时器) | RTC(独立实时时钟) |
精度 | 1ms(默认) | 1秒或更高(依赖配置) |
用途 | 短时计时、延时 | 长时间日历时间记录 |
是否需要初始化 | 自动由 HAL 初始化 | 需手动配置 RTC 和备份域 |
断电后是否持续 | 否(系统复位后归零) | 是(依赖备份电池) |
溢出周期 | 约 49.7 天 | 取决于计数器位数(通常数十年) |
如何选择?
-
短时计时/延时(如按键消抖、任务调度)
→ 用HAL_GetTick()
,简单高效。 -
长时间记录/日历时间(如数据日志、事件时间戳)
→ 用 RTC 相关函数(HAL_RTC_GetTime()
+HAL_RTC_GetDate()
)。 -
高精度需求(如 μs 级)
→ 需使用硬件定时器(如 TIMx),而非 SysTick 或 RTC。