STM32之时钟

1. 什么是时钟

1.1 时钟和时钟树的概念

1.1.1 时钟:

• 时钟是指 为芯片内部的各个模块(片上外设)提供 时间基准 的信号源,是芯片正常工作的基础。我们在写程序之前,首先都需要给要使用的那个模块(外设)打开时钟。

• 时钟是一种方波信号,时钟的频率越快,外设工作效率就越高。

• 时钟其实也可以理解人的心跳。

1.1.2 时钟树,如图:


• 如上图,用一棵树的形式,生动形象表示单片机的时钟系统。

• 可以把时钟树理解为血液系统,为单片机的每个外设输送时钟信号(血液)。

• 时钟树上的树根表示晶振的来源(时钟的来源),树干表示产生SYSCLK那一部分,树枝表示的AHB,APB1和APB2这三条总线,树叶表示的片上外设。

• 其中时钟树可以为高速时钟树(几十MHz)和低速时钟树(几十kHz)。

1.2 分频器,锁相环和复用器,如图:

• 分频器:对频率做除法。

• 锁相环:对频率做乘法。

• 复用器:对频率做选择。

1.3 树根,如图:

• 树根就是时钟的来源,内部时钟有两个LSI,HSI但是内部的时钟精度不高。

• 时钟的来源有四种,LSI,LSE,HSI,HSE。

1.4 树干,如图:

• 树干:对时钟信号 进行加工 从而得到SYSCLK

• 如图,能得到的SYSCLK的三种情况:

• HSI得到的SYSCLK:方便,都是精度不高。

• 锁相环得到的SYSCLK:灵活,可以得到不同的 SYSCLK 频率。

• HSE得到的SYSCLK:精度高。

1.5 树枝,如图:

• 树枝其实就是上图的三条总线。

• 树叶指的就是片上外设,如图:

• 通过SYSCLK分频,可以进一步 得到 这三条总线相对应的时钟,也就是说对SYSCLK进行分频,得到的HCLK,PCLK1和PCLK2。

2. 时钟树编程

2.1 时钟树初始状态

• 初始状态:给单片机刚上电或者按了复位按钮之后,还没来得及执行相应代码,此时单片机的状态。如图:

• 此时在初始状态下,单片机上面的时钟为8MHz ,由HSI 提供,所以SYSCLK=HCLK=PCLK1=PCLK2=8MHz,此时的CPU(Cortex-M3的频率)也是8HMz。CPU 频率决定单片机代码的执行效率。

2.2 标准库的启动代码,如图:

• 在启动文件中,可以找到这一段的代码,其中单片机启动的时候,先是执行了SystemInit这一段代码,也就是先配置 系统时钟 为72MHz,然后在执行main里面的函数。

• 如图,经过SystemInit之后,时钟由 8HMz 变成 72MHz

2.3 时钟树的编程接口

• 这些编程接口一一对应时钟树的器件,总线等等。

• 配置的步骤,如图:

• 为什么那个3那里第三,而不是4那里第三。

• 4那里本质就是选择的SYSCLK信号源,3那里就是设置分配器系数,之后的分频系数不变,变仅仅就是信号源。而4就是改变的是信号源。

2.4 配置

2.4.1 步骤一

2.4.2 步骤二

2.4.3 步骤三

2.4.4 步骤四

2.5 代码

复制代码
#include "stm32f10x.h"


void SystemClock_Init();

int main(void)
{
   SystemClock_Init();
    
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
   
   GPIO_InitTypeDef gpio_initStruct = {0};
   
   gpio_initStruct.GPIO_Mode = GPIO_Mode_Out_OD;
   gpio_initStruct.GPIO_Pin = GPIO_Pin_13;
   gpio_initStruct.GPIO_Speed = GPIO_Speed_2MHz;
   
   GPIO_Init(GPIOC,&gpio_initStruct);
    
    
	while(1)
	{
        GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);
        
        for(uint32_t i = 0;i < 666666;i++);
        
        GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
        
        for(uint32_t i = 0;i < 666666;i++);
        
	}
}


void SystemClock_Init(){
    
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//开启指令预取
    FLASH_SetLatency(FLASH_Latency_2);//设置访问延迟
    
    //1.选择晶振
    RCC_HSEConfig(RCC_HSE_ON);
    while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);//等待HSE就绪
    
    //2.启动锁相环,并选择乘的系数
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待PLL就绪
    
    
    //3.配置HCLK,PCLK1,PCLK2
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    
    //4.配置SYSCLK的来源
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08);//判断当前来源是不是来自锁相环
    
  
}

2.6 配置FLASH指令预取

2.6.1 为什么会有指令预取

• 这是因为FLASH是存储代码(程序),而程序的执行是在CPU那里,但是又由于CPU的执行速度比FLASH快太多了,这就需要FLASH把要执行的指令放到一个缓冲区里面,等待CPU的执行,如图:

• 至于要不要访问延迟,就看时钟频率。但是本质还是Flash的速度比CPU慢太多了。

• 还有一点,这两端段代码需要在SYSCLK <= 8MHZ的时候执行。

2.6.2 片上外设开关和复位,如图:

• 注意如果调用复位电路,需要调用两次,一次是ENABLE,一次是DISABLE,相当于按下和松开的步骤。

相关推荐
czwxkn9 小时前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件
Love Song残响9 小时前
NVIDIA显卡终极优化指南
stm32·单片机·嵌入式硬件
qq_6725927510 小时前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉821810 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
国科安芯10 小时前
抗辐照MCU在精密时频系统中的单粒子效应评估与可靠性验证
单片机·嵌入式硬件·架构·制造·安全性测试
森焱森10 小时前
嵌入式硬件工程师应知 白银快速分析报告
linux·c语言·arm开发·嵌入式硬件·去中心化
czhaii10 小时前
单片机最佳入门多线程示例讲解
c语言·单片机
BackCatK Chen20 小时前
第 8 篇:TMC2240 电机正反转实现|DIR 引脚控制 + 代码优化(稳定不抖动)
stm32·单片机·嵌入式硬件·保姆级教程·电机正反转·tmc2240·dir引脚控制
星马梦缘21 小时前
EDA彩灯电路绘制
单片机·嵌入式硬件·物联网·pcb·eda·嘉立创
Forsete1 天前
LINUX驱动开发#9——定时器
linux·驱动开发·单片机