当前位置: 首页 > news >正文

【STM32】uwTick在程序中的作用及用法,并与Delay函数的区别

一、uwTick 的作用

1.系统时间基准

  • uwTick 是一个全局变量(volatile uint32_t),记录系统启动后的毫秒级时间累计值。默认情况下,它由 SysTick 定时器每 ​1ms 自动递增一次(通过 HAL_IncTick() 函数。
  • 例如,若系统运行了 5 秒,uwTick 的值约为 5000。

2.实现延时功能

  • HAL_Delay() 函数依赖 uwTick 实现阻塞延时。其原理是通过记录起始时刻的 uwTick 值,并在循环中持续比较当前值与起始值的差值,直到达到设定的延时时间。

3.时间戳生成

  • 通过 HAL_GetTick() 直接返回 uwTick,用于标记事件发生的时刻或计算时间间隔(如程序执行耗时)。

二、uwTick 的使用方法

1.基本延时操作

// 阻塞延时 100ms
HAL_Delay(100);
  • 内部逻辑:HAL_Delay() 调用 HAL_GetTick() 获取当前 uwTick,循环等待直至时间差达到设定值。 

2.时间间隔计算

uint32_t start = HAL_GetTick();
// 执行某些操作...
uint32_t elapsed_time = HAL_GetTick() - start; // 计算耗时(ms)
  •  注意事项:若时间差超过 uint32_t 最大值(约 49.7 天),需额外处理溢出问题。

3.高精度时间测量

结合 SysTick 的当前计数值(SysTick->VAL)和 uwTick,可提升时间分辨率至微秒级:

uint32_t start_ms, start_ticks, end_ms, end_ticks;
vGetStartTime(&start_ms, &start_ticks); // 记录起始时间
// 执行代码...
vGetIntervalTime(start_ms, start_ticks, &end_ms, &end_ticks); // 计算时间差
float us = end_ms * 1000 + (SysTick->LOAD - end_ticks) * (1e6 / SystemCoreClock); // 转换为微秒
  • SysTick 是递减计数器,SysTick->VAL 提供当前周期内的剩余计数值,与 uwTick 共同实现高精度计时。

三、配置与注意事项

1.时基源选择

  • 默认使用 SysTick 作为时基源,但可通过 CubeMX 切换为硬件定时器(如 TIM1),以规避中断优先级冲突或实现更高精度的延时。
  • 修改方法:在 CubeMX 的 SYS 配置中,选择其他定时器作为时基源。

2.中断优先级问题

  • 风险:在中断服务函数(ISR)中调用 HAL_Delay() 可能导致死锁。例如,若高优先级中断等待 SysTick(低优先级)更新 uwTick,SysTick 中断可能无法触发。
  • 修改方法

避免在中断中使用阻塞延时,改用非阻塞计时(如标志位 + 轮询)。

 修改 SysTick 中断优先级至更高等级(需同步调整其他中断优先级)。

3.自定义时基频率 

  • 通过调整 uwTickFreq 可改变 uwTick 的更新频率(如改为 10kHz):
uwTickFreq = 10; // 10kHz(每 0.1ms 更新一次)
HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq));
  • 注意:需同步修改 HAL_GetTick() 相关逻辑以适配新频率。

 四、uwTick和Delay函数的核心区别

特性uwTickHAL_Delay()
本质全局变量(volatile uint32_t阻塞延时函数
作用记录系统启动后的毫秒级累计时间基于 uwTick 实现固定时长的阻塞延时
更新方式由 SysTick 或硬件定时器中断自动递增无直接操作,依赖 uwTick 的更新
用途时间戳生成、非阻塞计时、任务调度简单延时、代码流程控制
中断安全性可在中断中使用(需注意优先级冲突)禁止在高优先级中断中使用(可能导致死锁)

 五、HAL_Delay()的用法

1.底层原理

  •  HAL_Delay() 是阻塞函数,通过循环检查 uwTick 的差值实现延时。其核心逻辑如下:
void HAL_Delay(uint32_t Delay) {
    uint32_t tickstart = HAL_GetTick();  // 获取起始时间
    uint32_t wait = Delay;
    wait += uwTickFreq;  // 强制至少延时一个时基周期(默认+1ms)[3,4](@ref)
    while ((HAL_GetTick() - tickstart) < wait) {}  // 阻塞等待[5,7](@ref)
}
  •  误差特性:默认存在 ​**+1ms** 的固定误差(如 HAL_Delay(100) 实际延时 101ms)。

2.典型应用场景

  • 简单延时控制
HAL_Delay(500);  // 阻塞延时500ms(实际501ms)
  • 外设初始化等待:用于传感器上电稳定、通信协议间隔等场景。

3.注意事项

  • 禁止在高优先级中断中使用:可能导致 SysTick 中断无法触发,uwTick 停止更新,函数永不返回。
  • 替代方案:在高实时性场景中,改用硬件定时器或非阻塞计时(基于 uwTick)。

六、关键差异总结

1.角色不同

  • uwTick 是 ​时间基准变量,提供系统时间数据。
  • HAL_Delay() 是 ​延时工具函数,依赖 uwTick 实现功能。

2.使用场景

  • uwTick 适用于需要主动获取时间信息的场景(如性能分析、任务调度)。
  • HAL_Delay() 适用于简单的阻塞等待(如初始化等待、调试指示灯闪烁)。

3.实时性影响

  • HAL_Delay() 会阻塞 CPU,影响系统响应;uwTick 的非阻塞用法更适用于多任务系统。

相关文章:

  • redis三主三从集群部署
  • Logic-RL:小参数qwen模型复现DeepSeek R1 zero
  • 自学软硬件第755 docker容器虚拟化技术
  • 图解Spring-解决循环依赖流程
  • 使用 OpenSSL 构建安全的网络应用
  • 前端开发概论
  • 网易云信架构升级实践,故障恢复时间缩至8秒
  • TDengine 支持的所有运算符
  • 零基础学python+人工智能ai(持续更新ing)
  • 【MySQL】基本查询(下)
  • 什么是MCP(Model Context Protocol)?对话、意图识别、服务调用和上下文管理
  • django self.get_queryset() 如何筛选
  • Flask实时监控:打造智能多设备在线离线检测平台(升级版)
  • 素数判定方法详解:从基础试除法到优化策略
  • linux系统 Ubuntu22.04安装Nvidia驱动,解决4060系列显卡重启黑屏方法
  • c语言笔记 结构体内嵌套结构体的表示方式
  • 二维前缀矩阵
  • 十七、实战开发 uni-app x 项目(仿京东)- 后端指南
  • 5.0 VisionPro调用USB相机的方法与步骤说明(一)
  • Vue 渲染 LaTeX 公式 Markdown 库
  • 玛丽亚·凯莉虹口连唱两夜,舞台绽放唤醒三代人青春记忆
  • 北邮今年本科招生将首次突破四千人,新增低空技术与工程专业
  • 广西壮族自治区党委副书记、自治区政府主席蓝天立接受审查调查
  • 特朗普公开“怼”库克:苹果不应在印度生产手机
  • 国家统计局:2024年城镇单位就业人员工资平稳增长
  • 四个“从未如此”使巴以加沙战火绵延时间创下历史之最