24位掩码修正

发布于:2025-04-18 ⋅ 阅读:(36) ⋅ 点赞:(0)

可以跳转最后看


24 位掩码修正法的原理与限制(需 LOAD=0xFFFFFF

1. 核心原理

当 SysTick 的 LOAD 值设置为 0xFFFFFF(24 位最大值)时,其计数器行为与 24 位模运算 完全一致。此时:

  • VAL 寄存器 始终在 0x0000000xFFFFFF 之间循环递减。
  • 时间差计算:通过 (LastTick - CurrentVal) & 0xFFFFFF,利用 24 位掩码隐式处理溢出,直接得到正确的周期差。
2. 关键假设
  • LOAD = 0xFFFFFF:必须确保 SysTick 的加载值为 24 位最大值。
  • 计数器行为:VAL 从 0xFFFFFF 开始递减,到 0x000000 后自动重载为 0xFFFFFF

3. 计算示例

假设 LastTick = 0x100(即 256),当前 CurrentVal = 0xFFFFF000(即 0xFFF000 的 24 位掩码值):

  1. 直接计算
    0x100 - 0xFFF000 = -0xFFEE00(负值)
  2. 应用 24 位掩码
    (-0xFFEE00) & 0xFFFFFF = 0x001200(即 0x1200 = 4608 周期)
  3. 实际周期差
    • LastTick 从 0x100 递减到 0x000000:256 周期
    • 重载后从 0xFFFFFF 递减到 0xFFF000:0xFFFFFF - 0xFFF000 = 0x0FFF(4095 周期)
    • 总周期 = 256 + 4095 = 4351 周期
  4. 掩码法结果误差
    0x001200 = 4608 ≠ 4351(误差 257 周期)

结论:即使 LOAD=0xFFFFFF,此方法仍存在误差,需进一步验证。


4. 正确性验证(修正逻辑)

实际正确算法应为:


周期差 = (LastTick >= CurrentVal) ?
(LastTick - CurrentVal) :
(LastTick + 0x1000000 - CurrentVal)
  • LOAD=0xFFFFFF0x1000000 即 24 位模数。
  • 示例修正
    LastTick=0x100, CurrentVal=0xFFF000
    周期差 = 0x100 + 0x1000000 - 0xFFF000 = 0x100 + 0x1000 = 0x1100(4352 周期)
    (与实际 4351 周期误差 1,因未考虑从 0 到 0xFFFFFF 的重载周期)

5. 适用条件与限制

条件/限制 说明
必须 LOAD=0xFFFFFF 确保计数器周期与 24 位掩码的模数一致
误差来源 未计入从 0x0000000xFFFFFF 的重载周期(偏差 ±1 周期)
适用场景 对时间精度要求不严格(如粗略延时),且无法动态获取 LOAD 值的场合
不适用场景 LOAD≠0xFFFFFF 或需高精度计时(如通信超时检测)

6. 代码实现(LOAD=0xFFFFFF)

c


// 假设已设置 LOAD=0xFFFFFF
uint32_t LastTick = SysTick->VAL;
// ... 等待某些操作
uint32_t CurrentVal = SysTick->VAL;
// 24位掩码法计算时间差
uint32_t elapsed = (LastTick - CurrentVal) & 0x00FFFFFF;
// 等效正确计算(需 LOAD=0xFFFFFF)
uint32_t elapsed_correct = (LastTick >= CurrentVal) ?
(LastTick - CurrentVal) :
(LastTick + 0x01000000 - CurrentVal);

7. 总结

  • 掩码法本质:将时间差计算转换为 24 位无符号数运算,依赖 LOAD=0xFFFFFF 保证周期性。
  • 误差范围:±1 周期(因忽略重载时的 0xFFFFFF → 0x000000 跳变)。
  • 推荐场景:仅当硬件强制 LOAD=0xFFFFFF 且对误差不敏感时使用,否则应使用 溢出感知算法
正确方法选择优先级:
  1. 动态获取 LOAD + 溢出感知计算(通用、精确)
  2. 24 位掩码法(需严格满足 LOAD=0xFFFFFF,快速但轻微误差)

验证

假设在lasttick=2,当tick递减到0随后继续递减,则nowtickvalue=0XFFFFFF,则此时计数值为0X2-0xFFFFFF=FF000003,这个值&0XFFFFFF,为3,计数值正确。