Skip to content

复位以及时钟控制(RCC)

复位

有三种复位

  • 系统复位: 将复位除了时钟控制寄存器CSR中的复位标志和备份区域以内的寄存器以外的所有寄存器
  • 电源复位: 复位除了备份区域以外的所有寄存器
  • 后备域复位: 备份区有两个专门的复位, 只影响备份区域

当以下事件中的一件发生时,产生一个系统复位: 1. NRST引脚上的低电平(外部复位) 2. 窗口看门狗计数终止(WWDG复位) 3. 独立看门狗计数终止(IWDG复位) 4. 软件复位(SW复位) 5. 低功耗管理复位

通过查看RCC_CSR控制状态寄存器中的复位状态标志位识别复位事件来源

当以下事件中之一发生时,产生电源复位: 1. 上电/掉电复位(POR/PDR复位) 2. 从待机模式中返回

当以下事件中之一发生时,产生备份区域复位。 79/754 1. 软件复位,备份区域复位可由设置备份域控制寄存器(RCC_BDCR)(见7.3.9节)中的 BDRST位产生。 2. 在VDD和VBAT两者掉电的前提下,VDD或VBAT上电将引发备份区域复位。

  • 备份域BKP

备份寄存器是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域 里,当VDD电源被切断,他们仍然由VBAT维持供电。用户可以在这一部分区域保存自己的数据

开发板上的电池对着一部分进行供电

RCC时钟

时钟是芯片的心跳, STM32有很多种时钟的来源, HSI高速内部时钟, HSE高速外部时钟, PLL, 锁相环倍频时钟, 还有一些二级时钟, 内部低速时钟LSI, LSE外部低速时钟32.768KHz(主要用于RTC)

  • 内部时钟以及外部时钟

image-20231116114402843

内部时钟成本低, 但是没有外部时钟的稳定性高

使用不同的频率的时钟, 消耗的能量更高

image-20231116114204137

使用CubeMX可以进行时钟的设置

使用CubeMX进行配置

外部的高速时钟通常是外部的晶振或者用户的输入

选择之后就可以使用时钟配置进行操作了

不设置的话默认使用的是HSI, 8MHz, 这里可以手动设置, 或者在系统时钟输入对应的数字自动生成

在数据手册中有各个时钟所对应的最高频率的时钟

互联型的芯片的某一些时钟并不是从系统时钟获取时钟的, 需要单独考虑

使用F4以及H7系列的芯片的时候可以通过配置提高最高的时钟频率, 但是会增加芯片的耗能

image-20231116230729825

其他芯片的时钟

image-20231116114538415

APB1和APB2是挂载在AHB1上面的, 可能有2-3个AHB总线

image-20231116114646955

这个是f429, 不满足f407, 主要是下面的PLL锁相环的数量的区别

PLL里面的VCC是用来稳定频率用的, 分出来的48MHz一般是给USB时钟使用的

以太网和高速USB需要外部的始终提供频率

  • f407

image-20231118100612737

四个时钟源, 和f1的区别的是实际支持的频率不同

image-20231118100746809

image-20231118100758471

image-20231118100823666

USB必须是48MHz, 满足USB会导致系统超频, 但是这个是芯片允许的, 可以正常使用的

  • F7
image-20231118104005264

image-20231118104035867

image-20231118104050143

image-20231118104110813

  • H7

image-20231118111206572

image-20231118111231765

image-20231118111254923

对了一个低功耗的时钟, franc为一个小数的倍频

image-20231118111307800

image-20231118111324945

image-20231118111344488

image-20231118111403155

配置系统时钟

系统时钟配置步骤

  1. 配置HSE_VALUE的值, 在文件stm32xxxx_hal_config.h文件里面
  2. 调用SystemInit()函数, 在启动文件里面调用, system_stm32xxxx.c文件里面
  3. 选择时钟源, 配置PLL, HAL_RCC_OscConfig()
  4. 选择系统时钟源, 配置总线分频器HAL_RCC_ClockConfig()
  5. 配置扩展外设时钟可选, HAL_RCCEx_PeriphCLKConfig()

3+4+5 = sys_stm32_clock_init()正点原子配置的函数

外设时钟的使能失能

使用某一个外设的时候需要使能一个外设的时钟

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_DISABLE();

正点原子的初始化函数

主要使用的是

HAL_RCC_OscConfig(), HAL_RCC_ClockConfig()

c
void Stm32_Clock_Init(u32 PLL)
{
    HAL_StatusTypeDef ret = HAL_OK;
    RCC_OscInitTypeDef RCC_OscInitStructure; 
    RCC_ClkInitTypeDef RCC_ClkInitStructure;
    
    RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;    	//时钟源为HSE
    RCC_OscInitStructure.HSEState=RCC_HSE_ON;                      	//打开HSE
	RCC_OscInitStructure.HSEPredivValue=RCC_HSE_PREDIV_DIV1;		//HSE预分频
    RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;					//打开PLL
    RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;			//PLL时钟源选择HSE
    RCC_OscInitStructure.PLL.PLLMUL=PLL; 							//主PLL倍频因子
    ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化
	
    if(ret!=HAL_OK) while(1);
    
    //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;		//设置系统时钟时钟源为PLL
    RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;				//AHB分频系数为1
    RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV2; 				//APB1分频系数为2
    RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV1; 				//APB2分频系数为1
    ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_2);	//同时设置FLASH延时周期为2WS,也就是3个CPU周期。
		
    if(ret!=HAL_OK) while(1);
}

image-20231118114904703

HSI由于温度变化会有偏差, 所以需要一个校准值

image-20231118115325311

image-20231118115412210

image-20231118115508211

设置的是FLASH_ACR寄存器的LATENCY位, 在闪存编程手册里面

主要是为了CPU和FLASH的频率进行配对(72MHz-24MHz)

image-20231118120030654

其他芯片初始化

image-20231118205328947

image-20231118212354151

image-20231118212406338

image-20231118212426921

image-20231118212445550

image-20231118212456632