在利用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的时基.