两棵树
分为大树和小数,但是铁头山羊目前只讲了大树
RCC结构与四个时钟信号
有哪些时钟信号
四个时钟信号分别是SYSCLK,HCLK,PCLK1,PCLK2,片上外设一般是关闭状态的,想要使用需要开时钟,也就是这四个时钟信号,不同的外设对应的时钟是不一样的。四个时钟信号,SYSCLK信号经过AHB分频器变HCLK,HCLK分别经过APB1分频器和APB2分频器变为PCLK1和PCLK2
分频器可填参数
锁相环(分频器)可填参数
细节结构1:分频器
计数器里填7,输入来信号7个到达最大值,再来一个变回0并输出一个脉冲,也就是说分频系数=计数器周期+1
细节结构2:锁相环
锁相环看不懂,先记着,需要了再学
四个时钟源以及系统时钟来源
四个时钟源
HSE:高速外部时钟,HSI:高速内部时钟,LSE:低速外部时钟,LSI:低速内部时钟
小树给RTC,固定为32.768KHZ(2的15次方),是低速的,L开头,大树给片上外设,高速,H开头
系统时钟来源
系统时钟有三个来源
1:直接来自HSI高速内部时钟
2:直接来自HSE高速外部时钟
3:来自锁相环(倍频器)
锁相环也有三个来源:
1:HSI高速内部时钟除以2
2:HSE高速内部时钟除以2
3:HSE直接给
总结下就是
1:直接来自HSI高速内部时钟
2:直接来自HSE高速外部时钟
3:HSI高速内部时钟除以2再翻倍
4:HSE高速内部时钟除以2再翻倍
5:HSE高速内部时钟直接翻倍
计算例子
系统时钟计算例子
频率运算例子
标准库接口:外设使能和禁止以及复位
这里的标准库接口是用来"使用时钟"的
改变CPU频率实验
改变CPU频率思路以及验证改变成功的思路梳理
改变CPU频率
CPU频率就是Cortex-M3的频率,如图,对应的是AHB分频后的HCLK,理论上设置CPU频率只需设置SYSCLK来源以及各分频器,倍频器即可,但是改变了SYSCLK后,如果FLASH(相当于计算机的外存,或者说硬盘)的参数不跟着改变,会出现错误,所以改变SYCLK之前需要先改变FLASH参数,之后顺理成章的设置SYSCLK来源以及各分频器,倍频器,最后为了验证设置的CPU频率是否奏效,可以写一个延迟函数,来计算CPU频率是否设置成功。
延迟函数验证方法
CPU的时钟来自于HCLK,时钟周期和频率是倒数关系,假设HCLK为72MHZ,那一秒就有72M个HCLK时钟周期,CPU执行一个for循环需要执行6个时钟周期的时间,12M次会执行72M个时钟周期的时间,也就是1秒钟,每个for循环后改变LED状态,若为每秒改一下,则CPU频率设置就成功了,可以多试几个CPU频率,并改变对应的for循环次数
改变CPU频率之前,先验证一下延迟函数可行性
上电后RCC的初始状态
SYSCLK来源是HSI,各分频器系数为1
延迟出错以及原因以及解决方法
先验证一下延迟函数的思路:由上电后初始状态以及RCC的结构来看,CPU频率为8M,也就是一秒=8M个时钟周期,for循环一次是6个时钟周期的时间,想要延迟一秒需要8M个时钟周期,也就是8M/6次,但是代码写完发现闪烁速度快的多。铁头山羊给出了原因:上电之后执行main前会执行一个时钟初始化函数,在启动文件里可以找到
这个时钟初始化函数将时钟设置成了72M,这样我们写代码时就不用自己设置了,开时钟就完事。
将那两行时钟初始化函数注释(用";"注释)后,再次验证1333333个次for循环发现确实是每秒改变一次状态。
上面是验证了延迟函数验证CPU频率,接下来进行更改CPU频率实验。
改变CPU频率
设置FLASH参数
访问延迟
更改CPU之前需要先更改FLASH的参数以免出错,主要是更改FLASH的"访问延迟",单片机的结构类似于一个电脑,看这个图,CPU和FLASH之间有一个总线矩阵,总线矩阵在SYSCLK下向FLASH读取数据,FLASH最高频率是24M,也就是说每秒最多给24M次数据,(1/24M)秒给一次,如果SYSCLK时钟频率为36M,那就是每(1/36M)秒需要一次数据,FLASH来不及给出,就可能出错,所以需要再等一次,(1/18M)秒才拿数据,这时FLASH已经准备好数据了
指令预取
除了访问延迟,还有指令预取,这个不开应该也不会出错,但是开了速度会快一些,就是·在CPU和FLASH之间加了两个缓存,在CPU读取并处理一个数据时,可以把另一个数据放入缓冲区,这样快一些,更快地原因应该是CPU读取缓冲区速度要比FLASH快,所以把这个CPU在处理一个数据之后,虽然都是需要从一个地方拿数据,但从缓冲区拿数据要比从FLASH拿数据要快
最后一点就是更改FLASH要在SYSCLK<=8M时改变(给自己提个醒,CPU对应的是HCLK,FLASH实在SYSCLK<=8时可以更改,怕以后的自己弄混),刚上电正好8M,所以可以更改
最后用延迟函数验证:SYSCLK频率是8M*9=72MHZ,一秒有72M个时钟周期,for循环一次6个时钟周期,延迟一秒需要72M个时钟周期也就是72M/6=12M次,LED闪烁频率正确。
代码编写
接下来就是配置FLASH参数:打开指令预取和访问延迟,然后更改RCC的参数:开启HSE,SYSCLK来源换成HSE直接倍频(SYSCLK来源:锁相环,锁相环来源:直接来自于HSE),然后倍频器9倍,AHB分频系数为1,PCLK1和PCLK2分频系数分别为2,1,再关闭HSI
整体代码
编程接口
补充一个整体结构图
数据手册里的