最近换芯片被编程时钟困扰,想着看32的时钟举一反三一下
先随便贴个32的时钟树
不知道写32的人是否和我一样,在学习的时候学的是标准库,学标准库的时候都是文件复制粘贴用最高的频率,不需要考虑时钟的事情,只是初略的看了下,而在工作中就直接用cubemx配置时钟树了。从来没细细的去理解代码中的时钟是怎么样运作的。
晶振是人为配置的,而mcu是怎么得到我们的频率呢?
事实上,mcu不能得知我们用的是多少频率的晶振,换言之没有一个寄存器是让你写入晶振的频率的,所有mcu关于时钟的配置都是分频/倍频配置,外设中最典型的就是定时器,定时器的时间都是我们自己人为以apb速率用公式算出来然后将算出来的值填入各种分频和计数值得到的。
那么你有没有想过,既然mcu不知道它自己的频率,那么在速率类的外设配置的时候呢?比如usart设置115200的波特率,波特率是一个定值,mcu只会分频不知道它自己的频率他怎么以特定的速率发送呢?
事实上在程序中,系统时钟的频率这个值是我们自己写的,而最终填入波特率这个寄存器的也只是根据我们写的那个频率在程序中进行计算得出的一个分频的数
定位一下在hal库的位置
嘀嗒定时器是一个内核外设,可以看这三个函数
HAL_InitTick //初始化系统嘀嗒定时器中断
SysTick_Handler//中断执行函数
HAL_Delay//我们经常用的ms级定时
HAL_Delay的原理就是轮询SysTick_Handler里的累计变量直到我们设置的ms值
里面你会发现一个全局变量
这个SystemCoreClock变量就是系统内核的时钟,在cubemx生成的hal库中继续定位
发现在SystemClock_Config HAL_RCC_ClockConfig有这么一句语句
打开进去,看见HSI_VALUE,HSE_VALUE,pllclk了吗?由于代码太长我就不贴了
再来看看usart的波特率设置
从HAL_UART_Init入手,UART_SetConfig里有这么一部分代码
结论:SystemCoreClock为系统的时钟,在RCC中初始化成选择的hse/pll/hsi值,这个值是cubemx/自己配的,各个外设的时间都是调用这个SystemCoreClock计算分频来写入分频寄存器,