STM32F1时钟(详解)

一、时钟树图表

在这里插入图片描述RCC相关寄存器

//RCC 寄存器结构,RCC_TypeDeff,在文件“stm32f10x.h”中定义如下
     
    1059->1081行。:  
    typedef struct  
    {  
    vu32 CR;                  //HSI,HSE,CSS,PLL等的使能  
    vu32 CFGR;              //PLL等的时钟源选择以及分频系数设定 
    vu32 CIR;                // 清除/使能 时钟就绪中断 
    vu32 APB2RSTR;      //APB2线上外设复位寄存器 
    vu32 APB1RSTR;      //APB1线上外设复位寄存器 
    vu32 AHBENR;         //DMA,SDIO等时钟使能 
    vu32 APB2ENR;       //APB2线上外设时钟使能 
    vu32 APB1ENR;      //APB1线上外设时钟使能 
    vu32 BDCR;           //备份域控制寄存器 
    vu32 CSR;             
    } RCC_TypeDef; 

二、时钟详解(结合时钟树)

HSE时钟(72M)
HSE:High Speed-External Clock signal,即高速的外部时钟
来源:无源晶振(4-16M),通常使用8M
控制:RCC CR时钟控制寄存器的位16:HSEON控制

HSI时钟
HSI:Low Speed Internal Clock signal,高速的内部时钟
来源:芯片内部,大小为8M,当HSE故障时,系统时钟会自动切换到HSI,直到HSE启动成功。
控制:RCC_CR时钟控制寄存器的位0:HSION控制

锁相环时钟
锁相环时钟:PLLCLK(官方72M,实际64M)
来源:(HSI2、HSE)经过倍频所得。(常用HSE)
控制:CFGR:PLLXTPRE、 PLLMUL
注意:PLL时钟源头使用HIS/2的时候, PLLMUL最大只能是16,这个时候 PLLCLK最大只能是64M,小于ST官方推荐的最大时钟72M。

系统时钟
锁相环时钟:SYSCLK,最高为72M(ST官方推荐的)
来源:HSI、HSE、 PLLCLK。
控制:CFGR:SW
注意:通常的配置是 SYSCLK= PLLCLK=72M

HCLK时钟
HCLK:AHB高速总线时钟,速度最高为72M。为AHB总线的外设提供时钟、为 Cortex系统定时器提供时钟
( SysTick)、为内核提供时钟(FCLK)
AHB:advanced high- performance bus。
来源:系统时钟分频得到,一般设置HCLK= SYSCLK=72M
控制:CFGR:HPRE

PCLK时钟
PCLK1:APB1低速总线时钟,最高为36M。为APB1总线的外设提供时钟。2倍频之后则为APB1总线的定时器2-7提供时钟,最大为72M。
来源:HCLK分频得到,一般配置PCLK1=HCLK/2=36M
控制:RCC CFGR时钟配置寄存器的PPRE1位

PCLK2时钟
PCLK2:APB2高速总线时钟,最高为72M。为APB1总线的外设提供时钟。为APB1总线的定时器1和8提供时钟,最大为72M。
来源:HCLK分频得到,一般配置PCLK1=HCLK=72M
控制:RCC CFGR时钟配置寄存器的PPRE2位

RTC时钟
RTC时钟:为芯片内部的RTC外设提供时钟。
来源:HSE RTG(HSE分频得到)、LSE(外部32.768KHz的晶体提供)、LSI(32KHZ)。
控制:RCC备份域控制寄存器 RCC BDCR:RTCSEL位控制
独立看门狗时钟:TWDGCLK,由LS提供

Mco时钟输出
Mco:microcontroller clock output,微控制器时钟输出引脚,由PA8复用所得。
来源:PLLCLK/2,HSE、HSI、 SYSCLK
控制:CRGR:MCO
(自己写时钟配置函数,检测对错,利用Mco输出引脚,通过示波器看波形)

时钟安全系统(CSS)
时钟安全系统可以通过软件被激活。一旦其被激活,时钟监测器将在HSE振荡器启动延迟后被使能,并在HSE时钟关闭后关闭。
如果HSF时鈾发生故障,HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和TIM8)的刹车输入端,并产生时钟安全中断CSS,
允许软件完成营救操作。此CS中断连接到CortexTM-M3的NMI中断(不可屏蔽中断)
注意:一日CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并NMI也自动产生。MM将被不断执行,直到CSS中断挂起位被清除。
因此,在NM的处理程序中必须通过设置时钟中断寄存器( RCC CIR)里的CSSC位来清除CSS中断。
如果HSE振荡器被直接或间接地作为系统时钟,(间接的意思是:它被作为PLL输入时钟,并且PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡器被关闭。
在时钟失效时,如果HSE振荡器时钟(被分频或未被分频)是用作系统时钟的PLL的输
(如果HES出故障,且没有使能CSS,系统时钟切换到HSI(8M低速运行))

HSE=高速外部时钟信号
HSI=高速内部时即信号
LSI=低速内部时钟信号
LSE=低速外部时钟信号

三、 时钟配置思路:

系统时钟—>AHB分频器—>各个外设分频倍频器 —> 外设时钟的设置

1、使用为外部的高速时钟信号【HSE(8M不分频)】来配置时钟
2、然后进入锁相环时钟时钟源(PLLCLK)–配9倍频—>8*9=72M
3、结果出来的锁相环时钟(PLLCLK)–为72M
4、配置系统时钟(三个选择HSE/PLLCLK/HSI)我们选择锁相环时钟(PLLCLK)为系统时钟(SYSCLK)
5、如果APB1–选择2分频=36M,或APB2–选择1分频
(以上总线配置好了)
6、剩下其它外设使用时配置

RCC初始化思路

这里使用HSE(外部时钟),正常使用的时候也都是使用外部时钟

程序设置时钟参数流程:
1、将RCC寄存器重新设置为默认值 RCC_DeInit;
2、打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON);
3、等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、设置AHB时钟 RCC_HCLKConfig;
5、设置高速AHB时钟 RCC_PCLK2Config;
6、设置低速速AHB时钟 RCC_PCLK1Config;
7、设置PLL RCC_PLLConfig;
8、打开PLL RCC_PLLCmd(ENABLE);
9、等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
10、设置系统时钟 RCC_SYSCLKConfig;
11、判断是否PLL是系统时钟 while(RCC_GetSYSCLKSource() != 0x08)
12、打开要使用的外设时钟 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

代码实现:

对RCC的配置函数(使用外部8MHz晶振)

系统时钟72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz TIMCLK=72M

void RCC_Configuration(void)
{
	//----------使用外部RC晶振-----------
	RCC_DeInit();			//初始化为缺省值
	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪
	
	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);	//Enable Prefetch Buffer
	FLASH_SetLatency(FLASH_Latency_2);		//Flash 2 wait state
	
	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//HCLK = SYSCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);			//PCLK2 =  HCLK
	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
	RCC_PLLCmd(ENABLE);			//Enable PLLCLK
 
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
	while(RCC_GetSYSCLKSource()!=0x08);		//Wait till PLL is used as system clock source
	
	//---------打开相应外设时钟--------------------
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟		 
}

四、固件库——系统时钟配置函数

static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

// ① 使能 HSE,并等待 HSE 稳定
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

// 等待 HSE 启动稳定,并做超时处理
do {
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while ((HSEStatus == 0)
&&(StartUpCounter !=HSE_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
HSEStatus = (uint32_t)0x01;
} else {
HSEStatus = (uint32_t)0x00;
}
// HSE 启动成功,则继续往下处理
if (HSEStatus == (uint32_t)0x01) {

//-----------------------------------------------------------
// 使能 FLASH 预存取缓冲区 */
FLASH->ACR |= FLASH_ACR_PRFTBE;

// SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
// 设置成 2 的时候,SYSCLK 低于 48M 也可以工作,如果设置成 0 或者1 的时候,
// 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
// 0:0 < SYSCLK <= 24M
// 1:24< SYSCLK <= 48M
// 2:48< SYSCLK <= 72M */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
// ② 设置 AHB、APB2、APB1 预分频因子
// HCLK = SYSCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
//PCLK2 = HCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
//PCLK1 = HCLK/2
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

//③ 设置 PLL 时钟来源,设置 PLL 倍频因子,PLLCLK = HSE * 9 = 72 MHz
RCC->CFGR &= (uint32_t)((uint32_t)
~(RCC_CFGR_PLLSRC
| RCC_CFGR_PLLXTPRE
| RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE
| RCC_CFGR_PLLMULL9);

// ④ 使能 PLL
RCC->CR |= RCC_CR_PLLON;

// ⑤ 等待 PLL 稳定
while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
}

// ⑥ 选择 PLL 作为系统时钟来源
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

// ⑦ 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
while ((RCC->CFGR&(uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){
}
} else {// 如果 HSE 启动失败,用户可以在这里添加错误代码出来
}
}

在这里插入图片描述

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸运的涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值