需求

今天调试的时候,重新配置了 systick 的周期,结果发现通过 systick 进行的延时,怎么都不准,检查了时钟配置,也是很正常。

解决

其实这个问题很简单,有两种可能,一个是配置的位置不对,一个是配置的数据不对。

重新配置位置不对

重新配置 systick 正常使用 HAL_SetTickFreq 这个函数,但是注意,这个函数必须在 main.c 中的 SystemClock_Config 之后调用才可以,否则无效。

因为 SystemClock_Config -> HAL_RCC_ClockConfig -> HAL_InitTick 这个 HAL_InitTick 使用了 uwTickFreq. 但是 uwTickFreq 已经设置了默认值。所以如果 HAL_SetTickFreq 这个函数调用的位置不对,就会导致配置之后,又被重新配置为默认值。

typedef enum
{
  HAL_TICK_FREQ_10HZ         = 100U,
  HAL_TICK_FREQ_100HZ        = 10U,
  HAL_TICK_FREQ_1KHZ         = 1U,
  HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;

HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */

配置数据不对

HAL_InitTick 中有如下配置:

/* Configure the SysTick to have interrupt in 1ms time basis*/
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
{
  return HAL_ERROR;
}

systickreload 寄存器只有 24 位,如果是 168M 频率,systick 为 1k,那么必然会超出寄存器的范围,导致出错,重新配置失败。所以,需要考虑系统主频和 systick 的频率,然后带入计算,保证在 24 位之内,才可以。

参考

STM32利用SYSTICK实现的延时函数突然不准了

新人学习STM32,明明设置的300ms延时,烧进去后成了2,3秒

STM32下SysTick的一个容易发生的错误,时钟频率设置

STM32入门:Systick(嘀嗒定时器)学习

STM32的SysTick时钟定时不准??【恢复】

填坑-关于SysTick定时器

STM32CubeMX自动生成SYSTICK配置

STM32 systick配置 基于stm32cube

STM32 HAL库 Systick使用笔记

HAL 库中的 SYS 时基源(Timebase Source)选择Systick/TIM区别,以及 SysTick_Handler()

STM32延时函数的四种方法:普通延时(2种)、SysTick 定时器延时(2种)