stm32学习笔记(10)时钟

mac2026-05-12  8

提前说说

学习32这么长时间了,中间有一段内容也比较生疏,比如就是这个时钟。那会初学,真的没有搞清楚,今天再次回过头复习一下,彻底把时钟这一部分弄清楚

时钟

时钟树 用户可通过多个预分频器配置AHB、高速APB(APB2)和低速APB(APB1)域的频率。AHB和 APB2域的最大频率是72MHz。APB1域的最大允许频率是36MHz。SDIO接口的时钟频率固定为HCLK/2。 RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。通过对SysTick 控制与状态寄存器的设置,可选择上述时钟或Cortex(HCLK)时钟作为SysTick时钟。ADC时钟 由高速APB2时钟经2、4、6或8分频后获得。 定时器时钟频率分配由硬件按以下2种情况自动设置:

如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致。否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。

这里总结一下 SystemInit()函数中设置的系统时钟大小: SYSCLK(系统时钟) =72MHz AHB 总线时钟(使用 SYSCLK) =72MHz APB1 总线时钟(PCLK1) =36MHz APB2 总线时钟(PCLK2) =72MHz PLL 时钟 =72MHz

SysTick滴答定时器

void delay_init() { #if SYSTEM_SUPPORT_OS //如果需要支持OS. u32 reload; #endif SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 #if SYSTEM_SUPPORT_OS //如果需要支持OS. reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为K reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间 //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位,为5 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK #else fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 #endif } SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8

这一段代码,就是选择delay函数的时钟,为72/8mhz,也就是9mhz。我是这么理解的,现在delay函数时钟为9mhz,那么它的单位就是1/(9mhz)=1/9us

fac_us=SystemCoreClock/8000000;

第二段代码是fac_us为72mhz/8000000,也就是9个单位,那么fac_us=9*(1/9)us=1us。以上是不是操作系统的情况。

这里我们将介绍的是 ALIENTEK 提供的最新版本的延时函数,该版本的延时函数支持在任 意操作系统(OS)下面使用,它可以和操作系统共用 SysTick 定时器。 这里,我们以 UCOSII 为例,介绍如何实现操作系统和我们的 delay 函数共用 SysTick 定时 器。首先,我们简单介绍下 UCOSII 的时钟:ucos 运行需要一个系统时钟节拍(类似 “心跳”), 而这个节拍是固定的(由 OS_TICKS_PER_SEC 宏定义设置),比如要求 5ms 一次(即可设置: OS_TICKS_PER_SEC=200),在 STM32 上面,一般是由 SysTick 来提供这个节拍,也就是 SysTick 要设置为 5ms 中断一次,为 ucos 提供时钟节拍,而且这个时钟一般是不能被打断的(否则就不 准了)。

因为在 ucos 下 SysTick 不能再被随意更改,如果我们还想利用 SysTick 来做 delay_us 或者 delay_ms 的延时,就必须想点办法了,这里我们利用的是时钟摘取法。以 delay_us 为例,比如 delay_us(50),在刚进入 delay_us 的时候先计算好这段延时需要等待的 SysTick 计数次数,这里 为 50 * 9(假设系统时钟为 72Mhz,那么 SysTick 每增加 1,就是 1/9us),然后我们就一直统计 SysTick 的计数变化,直到这个值变化了 50 * 9,一旦检测到变化达到或者超过这个值,就说明 延时 50us 时间到了。这样,我们只是抓取 SysTick 计数器的变化,并不需要修改 SysTick 的任 何状态,完全不影响 SysTick 作为 UCOS 时钟节拍的功能,这就是实现 delay 和操作系统共用 SysTick 定时器的原理。

最新回复(0)