HAL_GetTick() 是否返回刻度或毫秒?(以及如何以微秒为单位进行测量) [英] Does HAL_GetTick() return ticks or milliseconds? (and how to measure in microseconds)

查看:1055
本文介绍了HAL_GetTick() 是否返回刻度或毫秒?(以及如何以微秒为单位进行测量)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用 HAL 函数.函数HAL_GetTick() 的描述说它提供了一个刻度毫秒为单位的值.

I'm new to using HAL functions. The description of the function HAL_GetTick() says that it "provides a tick value in millisecond".

我不明白这个函数是返回滴答声还是毫秒.当然,要将滴答转换为毫秒,我需要知道一毫秒中有多少滴答,而且它是特定于 CPU 的.

I don't understand if this function returns ticks or milliseconds. Of course to convert from ticks to milliseconds I need to know how many ticks are in a millisecond, and it's CPU specific.

那么 HAL_GetTick() 究竟返回什么?

So what does HAL_GetTick() exactly return?

我真正的问题是知道如何以微秒为单位测量时间.所以我想从 HAL_GetTick() 获取刻度并将它们转换为微秒.这在评论中和至少在其中一个答案中得到了解决,所以我也在这里提到了这一点,并编辑了标题.

My real problem is knowing how to measure time in microseconds. So I thought to get ticks from HAL_GetTick() and convert them to microseconds. This is addressed in the comments and at least in one of the answers so I'm mentioning this here too and I edited the title.

推荐答案

HAL_GetTick() 应该返回自启动以来经过的毫秒数,因为很多 HAL 函数依赖在上面.你如何实现它取决于你.默认情况下,HAL_Init() 查询系统时钟速度,并将 SysTick 频率设置为它的 1/1000:

HAL_GetTick() should return the number of milliseconds elapsed since startup since a lot of HAL functions depend on it. How do you achieve it is up to you. By default, HAL_Init() queries the system clock speed, and sets the SysTick frequency to the 1/1000th of that:

__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /*Configure the SysTick to have interrupt in 1ms time basis*/
  HAL_SYSTICK_Config(SystemCoreClock /1000);

  /*Configure the SysTick IRQ priority */
  HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);

   /* Return function status */
  return HAL_OK;
}     

然后默认的 SysTick 中断处理程序调用 HAL_IncTick() 以每毫秒递增一次内部计数器,并且 HAL_GetTick() 返回该计数器的值.

Then the default SysTick interrupt handler calls HAL_IncTick() to increment an internal counter once every ms, and HAL_GetTick() returns the value of that counter.

所有这些函数都定义为weak,因此您可以覆盖它们,只要您的HAL_GetTick() 版本以毫秒为单位返回经过的时间,它就会没事.你可以例如替换 HAL_InitTick() 以让 SysTick 以 10 kHz 运行,但是您应该确保 HAL_IncTick() 仅在每 10 个中断时被调用.在 216 MHz STM32F7 控制器(或刚刚发布的 400 MHz STM32H743)上,您实际上可以降到 1 MHz Systick,但是您应该非常小心地尽快从处理程序返回.除非您在处理程序中执行硬件计数器无法执行的操作,否则这仍然会严重浪费宝贵的处理器周期.

All these functions are defined as weak, so you can override them, as long as your version of HAL_GetTick() returns the elapsed time in milliseconds, it'll be OK. You can e.g. replace HAL_InitTick() to let SysTick run at 10 kHz, but then you should ensure that HAL_IncTick() gets called only at every 10th interrupt. On a 216 MHz STM32F7 controller (or the barely released 400MHz STM32H743), you can actually go down to 1 MHz Systick, but then you should be very careful to return as quickly as possible from the handler. And it would still be a horrible waste of precious processor cycles unless you do something in the handler that a hardware counter can't.

或者您可以在不配置 SysTick 的情况下执行此操作(使用空函数覆盖 HAL_InitTick()),但设置一个 32 位硬件定时器,并使用足够的预分频器来计算每一微秒,并让 HAL_GetTick() 返回计时器计数器.

Or you may do it without configuring SysTick at all (override HAL_InitTick() with an empty function), but set up a 32-bit hardware timer with a sufficient prescaler to count on every microsecond, and let HAL_GetTick() return the timer counter.

回到真正的问题,以微秒为单位测量时间,有更好的方法.

Getting back to your real problem, measuring time in the order of microseconds, there are better ways.

如果您有可用的 32 位定时器,那么您可以将相应 APB 时钟的 MHz 值放入预分频器中,启动它,然后就有了您的微秒时钟,根本不会占用应用程序的处理时间.此代码应在 STM32L151/152/162STM32F4 上启用它(未测试):

If you have a 32-bit timer available, then you can put the MHz value of the respective APB clock in the prescaler, start it, and there is your microseconds clock, not taking away processing time from your application at all. This code should enable it (not tested) on a STM32L151/152/162STM32F4:

__HAL_RCC_TIM5_CLK_ENABLE();
TIM5->PSC = HAL_RCC_GetPCLK1Freq()/1000000 - 1;
TIM5->CR1 = TIM_CR1_EN;

然后通过读取TIM5->CNT随时获取其值.

then get its value anytime by reading TIM5->CNT.

查看您的参考手册,哪些硬件计时器具有 32 位计数器,以及它从哪里获取时钟.它在整个 STM32 系列中变化很大,但在 F4 上应该存在.

Check your reference manual which hardware timers have 32-bit counters, and where does it get its clock from. It varies a lot across the whole STM32 series but should be there on an F4.

如果您不能使用 32 位计时器,则可以使用核心周期计数器.只需启用一次

If you can't use a 32-bit timer, then there is the core cycles counter. Just enable it once with

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

然后从DWT->CYCCNT读取值.请注意,当它返回经过的处理器周期时,它会在几秒钟内溢出.

and then read the value from DWT->CYCCNT. Note that as it returns the elapsed processor cycles, it will overflow in a couple of seconds.

我刚刚注意到您使用的是 STM32L0.因此,忘记 32 位定时器和 200+ MHz 内核.使用DWT->CYCCNT,或者仔细考虑你想要测量的时间间隔是多长,精确度是多少,然后使用 16 位定时器.您可以将其作为一个单独的问题发布,更详细地描述您的硬件的外观以及它应该做什么.可能有一种方法可以通过您想要计时的事件直接触发计数器启动/停止..

I've just noted that you're using an STM32L0. So, forget 32-bit timers and 200+ MHz cores. Use DWT->CYCCNT, or think very carefully about how long are the intervals you'd like to measure, and with what accuracy, then take a 16-bit timer. You could post it as a separate question, describing in more detail how your hardware looks like and what it should it do. There might be a way to trigger a counter start/stop directly by the events you'd like to time..

这篇关于HAL_GetTick() 是否返回刻度或毫秒?(以及如何以微秒为单位进行测量)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆