Cortex-M4 上的 Systick 定时器:它的预分频器是啥?
Posted
技术标签:
【中文标题】Cortex-M4 上的 Systick 定时器:它的预分频器是啥?【英文标题】:Systick timer on Cortex-M4: What is its prescaler?Cortex-M4 上的 Systick 定时器:它的预分频器是什么? 【发布时间】:2021-01-18 04:24:42 【问题描述】:我对 Cortex-M4 CPU 上的 Cortex 系统计时器有点困惑。
假设我们有以下配置:
16MHz HSI 作为时钟源; AHB1 预分频器设置为 1(即 HSI 除以 1);这意味着主系统总线(即 AHB1 或 AHB)以每秒 16 000 000 个滴答的速度运行。就我而言,系统计时器(所谓的 SysTick)以主系统总线的速度运行,因此每秒最多应计数 16 000 000 次。这似乎很明显,但是当我查看 STM32F407xx 参考手册中的Clock tree
图时,我看到了:
看起来system timer
以(main system bus speed) / 8
的速度运行。
这是真的吗?我已将系统计时器配置为每 16 000 000 个滴答声产生中断。根据上面提供的配置(即 HSI 作为时钟源和 AHB1 预分频器 = 1),它每秒产生中断,从而打开和关闭 LED。我试图测量“闪烁”之间的时间,它似乎正好是 1 秒。如果有这个预分频器(即 /8),那么 LED 应该每 8 秒切换一次。
您可以在下面找到配置系统时钟源和系统定时器的代码。
HSI 频率 = 16 [MHz] SYSTICKS_COUNT = 16 000 000void system_clock_init(void)
LL_RCC_HSI_Enable();
while (LL_RCC_HSI_IsReady() != 1)
;
LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
;
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
void system_clock_systick_config_init(void)
SysTick_Config(SYSTICKS_COUNT);
void SysTick_Handler(void)
led_toggle(LED_PIN_BOARD_GREEN);
【问题讨论】:
"我已将系统计时器配置为每 16 000 000 个滴答声产生中断。"如何?您没有包含任何代码,而且很可能是因为某种原因配置错误,或者该配置不是您认为的那样(例如,考虑到 /8 分隔符)。 当然,我没有包含任何代码,因为这对我来说似乎很明显。让我编辑一下:) 如果将LL_RCC_SYSCLK_DIV_1
更改为LL_RCC_SYSCLK_DIV_8
会发生什么? LED 以什么频率闪烁?它回答了你的问题吗?
看看下面的答案,问题就隐藏在那里:)
【参考方案1】:
参考手册在“6.2 时钟”部分的末尾指出:
RCC 为 Cortex 系统定时器 (SysTick) 的外部时钟提供 AHB 时钟 (HCLK) 除以 8。SysTick 可以与此时钟或 Cortex 时钟一起工作 (HCLK),可在 SysTick 控制和状态寄存器中配置。
根据STM32 Cortex-M4编程手册SysTick控制寄存器(STK_CTRL)的Bit 2选择时钟源:
位 2 CLKSOURCE:时钟源选择 0:AHB/8 1:处理器时钟(AHB)
根据同一个手册,默认值应该是0(使用AHB/8)。显然在你的代码中的某个地方这个位被设置为 1 !?!
【讨论】:
非常感谢您提供这些信息。非常有趣,为什么这个位设置为 1。我需要验证这一点。现在我知道去哪里找了!谢谢! :) 知道了!从core_cm4.h
调用函数SysTick_Config()
将CLKSOURCE
位设置为1,这意味着系统定时器以AHB时钟的速度运行。以上是关于Cortex-M4 上的 Systick 定时器:它的预分频器是啥?的主要内容,如果未能解决你的问题,请参考以下文章