关于HAL库中系统嘀嗒时钟的简单探究

本文详细解析了如何在STM32工程中利用HAL库设置系统嘀嗒时钟,涉及初始化函数、频率配置、Systick频率选择及实际时钟值计算,助力理解低级别硬件配置过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在利用HAL库建立STM32工程时,系统嘀嗒时钟的初始化是在函数HAL_Init()中实现的:

HAL_StatusTypeDef HAL_Init(void)
{
  /* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
    defined(STM32F102x6) || defined(STM32F102xB) || \
    defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
    defined(STM32F105xC) || defined(STM32F107xC)

  /* Prefetch buffer is not available on value line devices */
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */

  /* Set Interrupt Group Priority */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
  HAL_InitTick(TICK_INT_PRIORITY); //初始化系统嘀嗒时钟

  /* Init the low level hardware */
  HAL_MspInit();

  /* Return function status */
  return HAL_OK;
}

打开HAL_InitTick()函数的定义:

__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /* Configure the SysTick to have interrupt in 1ms time basis*/
  if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) //配置频率
  {
    return HAL_ERROR;
  }

  /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); //配置中断优先级
    uwTickPrio = TickPriority;
  }
  else
  {
    return HAL_ERROR;
  }

  /* Return function status */
  return HAL_OK;
}

中断优先级无需多言,主要看Systick的频率配置,频率配置是通过函数HAL_SYSTICK_Config()完成的,先看内部参数:SystemcoreClock/(1000U/uwTickFreq)

打开SystemcoreClock的定义,发现其值为16M:

uint32_t SystemCoreClock = 16000000;

然而这只是初始值,在系统初始化时会将其赋值为预先配置好的系统频率(如72MHz),可以在系统初始化完成后把这个变量打印出来.

打开uwTickFreq的定义,发现是一个枚举类型的元素:

HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /这里默认利用Systick产生1ms的时基

打开枚举类型定义,得到uwTickFreq的值为1:

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;

//由于被1000(产生1ms时基)整除,所以产生10Hz的频率需要除以100,以此类推

至此,知道调用HAL_SYSTICK_Config()函数时的参数SystemcoreClock/(1000U/uwTickFreq),其值为72M/(1000/1)=72K.

打开HAL_SYSTICK_Config()的定义:

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) //由于系统嘀嗒定时器的重装载值寄存器为24位,不允许装载值大于FFFF FF
  {
    return (1UL);                              //返回1则配置失败                   
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         // 重装载值

  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); // 配置中断优先级 

  SysTick->VAL   = 0UL;                                             // 清空计数器 

  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |                    // 选择时钟源为FCLK
                   SysTick_CTRL_TICKINT_Msk   |                    // 允许异常请求
                   SysTick_CTRL_ENABLE_Msk;                        // 使能定时器

  return (0UL);                                                   //返回0则配置成功
}

在函数中将系统嘀嗒时钟的重装载值设置为72K,这样在72MHz的技术频率下就能产生1ms的时基.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值