【问题标题】:HAL_GetTick() always returns 0HAL_GetTick() 总是返回 0
【发布时间】:2023-04-09 16:45:01
【问题描述】:

我目前正在使用现有代码库开发一个项目,其中 HAL_GetTick() 在某些地方有效,但是当我尝试在其他文件中调用该函数时,它返回 0。 HAL_Delay() 出于某种原因确实有效。

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 做你的功课:使用调试器,放置断点,比较工作代码和非工作代码。 HAL_getTick 可能使用 SysTick。您是否检查过 SysTick 是否已启用?
  • 我正在使用黑盒系统,我无法在任何我想要的地方放置断点。我检查了 SysTick,它似乎工作正常。
  • 你写了“我在其他文件中调用函数”:不就是C文件调用C函数吗?
  • HAL_GetTick 什么都不做,只是返回一个在 SysTick 处理程序中递增的全局变量。检查您的 vectot 表,确保为 Systick 处理程序设置了正确的 HAL 功能,并且 systick 已很好地启用。

标签: stm32 hal stm32cubeide


【解决方案1】:

在我看来,您的代码库可能会覆盖该功能。请参阅有关 HAL_GetTick() 的帖子: STM32 and HAL function GetTick()

作为替代方案,您可以执行以下操作。如果你知道定时器的频率,你可以使用下面的代码 sn -p:

const uint32_t freq = 1000000; // Freq in Hz
uint32_t get_ticks() 
{
    uint32_t ticks = __HAL_TIM_GET_COUNTER(&htim2);
    return ticks;
}
double ticks_to_seconds(uint32_t ticks)
{
    double seconds = (double) ticks/freq;
    return seconds;
}

【讨论】:

    【解决方案2】:

    HAL 使用的内部(全局)滴答计数器变量在 ISR 中递增。如果您碰巧禁用了 IRQ,则计数器将不再增加。如果您在启动后根本没有启用中断,这同样适用。

    注意:您报告了(可重现的?)结果值0,这表明滴答计数器在通电后从未增加过。这向我们指出了您忘记的假设

    • 启用底层中断(SysTick 除非您选择了一些 TIM,例如在 CubeMX 中)
    • 全局启用中断
    • 在您将 CubeHAL SysTick/TIMx 处理程序代码替换为您自己的代码后保留它(

    【讨论】:

    • 我用 HAL_Init 初始化了 HAL,我不知道你所说的“全局启用中断”是什么意思
    • 我的意思是,您必须确保定时器中断(SysTickTIM 实例)可以实际触发。除了每个中断向量的激活/优先级之外,还有一个全局设置可以从 SW 动态启用/禁用中断。
    【解决方案3】:

    我忘了提到我也使用 LoRaWAN。显然 LoRaWAN 也有 HAL_InitTick() 和 HAL_Delay() 之类的函数。我得出的结论是 LoRaWAN 以某种方式覆盖了计时器。

    我解决这个问题的方法是进入 mlm32I0xx_hal_msp.c 并重新定义 HAL_GetTick():

    uint32_t HAL_GetTick(void){
       return HW_RTC_Tick2ms(HW_RTC_GetTimerValue());
    }
    

    希望我可以帮助其他人解决此问题。

    【讨论】:

      猜你喜欢
      • 2015-09-27
      • 2014-03-20
      • 2013-04-13
      • 2013-03-30
      • 2016-07-13
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      相关资源
      最近更新 更多