STM32_时钟树_寄存器操作

文章目录

  • 一、时钟相关寄存器
    • [   1、时钟控制寄存器(RCC_CR)](#   1、时钟控制寄存器(RCC_CR))
    • [   2、时钟配置寄存器(RCC_CFGR)](#   2、时钟配置寄存器(RCC_CFGR))
    • [   3、时钟中断寄存器 (RCC_CIR)](#   3、时钟中断寄存器 (RCC_CIR))
    • [   4、APB2 外设复位寄存器 (RCC_APB2RSTR)](#   4、APB2 外设复位寄存器 (RCC_APB2RSTR))
    • [   5、APB1 外设复位寄存器 (RCC_APB1RSTR)](#   5、APB1 外设复位寄存器 (RCC_APB1RSTR))
    • [   6、AHB外设时钟使能寄存器 (RCC_AHBENR)](#   6、AHB外设时钟使能寄存器 (RCC_AHBENR))
    • [   7、APB2 外设时钟使能寄存器(RCC_APB2ENR)](#   7、APB2 外设时钟使能寄存器(RCC_APB2ENR))
    • [   8、APB1 外设时钟使能寄存器(RCC_APB1ENR)](#   8、APB1 外设时钟使能寄存器(RCC_APB1ENR))
    • [   9、备份域控制寄存器 (RCC_BDCR)](#   9、备份域控制寄存器 (RCC_BDCR))
    • [   10、控制/状态寄存器 (RCC_CSR)](#   10、控制/状态寄存器 (RCC_CSR))
    • [   11、RCC寄存器地址映像](#   11、RCC寄存器地址映像)
  • 二、配置时钟寄存器代码

一、时钟相关寄存器

1、时钟控制寄存器(RCC_CR)

偏移地址: 0x00

复位值: 0x000 XX83,X代表未定义

访问: 无等待状态, 字, 半字 和字节访问

2、时钟配置寄存器(RCC_CFGR)

偏移地址: 0x04

复位值: 0x0000 0000

访问: 0到2个等待周期,字,半字和字节访问

只有当访问发生在时钟切换时,才会插入1或2个等待周期。

3、时钟中断寄存器 (RCC_CIR)

偏移地址: 0x08

复位值: 0x0000 0000

访问:无等待周期, 字, 半字 和字节访问

4、APB2 外设复位寄存器 (RCC_APB2RSTR)

偏移地址: 0x0C

复位值: 0x0000 0000

访问:无等待周期, 字, 半字 和字节访问

5、APB1 外设复位寄存器 (RCC_APB1RSTR)

偏移地址:0x10

复位值:0x0000 0000

访问:无等待周期,字, 半字和字节访问

6、AHB外设时钟使能寄存器 (RCC_AHBENR)

偏移地址:0x14

复位值:0x0000 0014

访问:无等待周期, 字, 半字 和字节访问

注: 当外设时钟没有启用时,软件不能读出外设寄存器的数值,返回的数值始终是0x0。

7、APB2 外设时钟使能寄存器(RCC_APB2ENR)

偏移地址:0x18

复位值:0x0000 0000

访问:字,半字和字节访问

通常无访问等待周期。但在APB2总线上的外设被访问时,将插入等待状态直到APB2的外设访问结束。

注: 当外设时钟没有启用时,软件不能读出外设寄存器的数值,返回的数值始终是0x0。

8、APB1 外设时钟使能寄存器(RCC_APB1ENR)

偏移地址:0x1C

复位值:0x0000 0000

访问:字、半字和字节访问

通常无访问等待周期。但在APB1总线上的外设被访问时,将插入等待状态直到APB1外设访问结束。

注: 当外设时钟没有启用时,软件不能读出外设寄存器的数值,返回的数值始终是0x0。

9、备份域控制寄存器 (RCC_BDCR)

偏移地址:0x20

复位值:0x0000 0000,只能由备份域复位有效复位

访问:0到3等待周期,字、半字和字节访问

当连续对该寄存器进行访问时,将插入等待状态。

注意: 备份域控制寄存器中(RCC_BDCR)的LSEON、LSEBYP、RTCSEL和RTCEN位处于备份域。

10、控制/状态寄存器 (RCC_CSR)

偏移地址:0x24

复位值:0x0C00 0000,除复位标志外由系统复位清除,复位标志只能由电源复位清除。

访问:0到3等待周期,字、半字和字节访问

当连续对该寄存器进行访问时,将插入等待状态。

11、RCC寄存器地址映像

RCC寄存器地址映像和复位值

二、配置时钟寄存器代码

1、配置系统时钟为72MHZ(HSE = 8MHZ晶振)

c 复制代码
		#include "stm32f10x.h"
		
		/**
		 * @brief  寄存器方式配置STM32F103系统时钟为72MHz(HSE=8MHz晶振)
		 * @param  无
		 * @retval 无
		 */
		void SystemClock_Config_Register(void)
		{
		    // 1. 开启HSE时钟(外部8MHz晶振),并等待HSE稳定
		    RCC->CR |= RCC_CR_HSEON;  // 置位HSEON位,开启HSE
		    while(!(RCC->CR & RCC_CR_HSERDY));  // 等待HSERDY位置1,HSE稳定
		
		    // 2. 配置时钟分频器
		    // FLASH延迟配置:72MHz下需要2个等待周期(必须配置,否则芯片会跑飞)
		    FLASH->ACR |= FLASH_ACR_LATENCY_2;  
		    // AHB分频:不分频(SYSCLK=72MHz → HCLK=72MHz)
		    RCC->CFGR &= ~RCC_CFGR_HPRE;        
		    // APB1分频:2分频(HCLK=72MHz → PCLK1=36MHz,APB1最大支持36MHz)
		    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;   
		    // APB2分频:不分频(HCLK=72MHz → PCLK2=72MHz,APB2最大支持72MHz)
		    RCC->CFGR &= ~RCC_CFGR_PPRE2;       
		
		    // 3. 配置PLL参数
		    RCC->CFGR &= ~RCC_CFGR_PLLSRC;      // 清空PLLSRC位(默认HSE作为PLL源)
		    RCC->CFGR &= ~RCC_CFGR_PLLXTPRE;    // HSE不分频输入到PLL(PLLXTPRE=0)
		    RCC->CFGR &= ~RCC_CFGR_PLLMULL;     // 清空PLL倍频位
		    RCC->CFGR |= RCC_CFGR_PLLMULL9;     // PLL倍频9倍(8MHz×9=72MHz)
		
		    // 4. 开启PLL,等待PLL稳定
		    RCC->CR |= RCC_CR_PLLON;            // 置位PLLON位,开启PLL
		    while(!(RCC->CR & RCC_CR_PLLRDY));  // 等待PLLRDY位置1,PLL稳定
		
		    // 5. 切换系统时钟源到PLL,等待切换完成
		    RCC->CFGR &= ~RCC_CFGR_SW;          // 清空系统时钟源选择位
		    RCC->CFGR |= RCC_CFGR_SW_PLL;       // 选择PLL作为系统时钟源
		    while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);  // 等待切换完成
		}
		
		// 主函数测试
		int main(void)
		{
		    SystemClock_Config_Register();  // 初始化系统时钟为72MHz
		    
		    while(1)
		    {
		        // 后续业务代码
		    }
		}

2、开启外设时钟(取所需代码)

c 复制代码
		#include "stm32f10x.h"
		
		/**
		 * @brief  寄存器方式开启所有外设时钟(按总线分类)
		 * 注意:实际开发中不要一次性开启所有外设,仅开启需要的外设以节省功耗
		 */
		void Periph_Clock_Enable_All(void)
		{
		    // ------------------- AHB总线外设时钟开启 -------------------
		    RCC->AHBENR |= RCC_AHBENR_DMA1EN;    // DMA1时钟
		    RCC->AHBENR |= RCC_AHBENR_DMA2EN;    // DMA2时钟(仅大容量型号有)
		    RCC->AHBENR |= RCC_AHBENR_SRAMEN;    // SRAM时钟
		    RCC->AHBENR |= RCC_AHBENR_FLITFEN;   // FLASH接口时钟
		    RCC->AHBENR |= RCC_AHBENR_CRCEN;     // CRC时钟
		    // 可选:SDIO、FSMC(仅部分型号支持)
		    // RCC->AHBENR |= RCC_AHBENR_SDIOEN;
		    // RCC->AHBENR |= RCC_AHBENR_FSMCEN;
		
		    // ------------------- APB2总线外设时钟开启 -------------------
		    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;  // 复用功能IO时钟(必须先开,否则GPIO复用功能用不了)
		    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;  // GPIOA时钟
		    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;  // GPIOB时钟
		    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;  // GPIOC时钟
		    RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;  // GPIOD时钟(仅大容量型号)
		    RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;  // GPIOE时钟(仅大容量型号)
		    RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;  // GPIOF时钟(仅大容量型号)
		    RCC->APB2ENR |= RCC_APB2ENR_IOPGEN;  // GPIOG时钟(仅大容量型号)
		    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;// USART1时钟
		    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;  // SPI1时钟
		    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;  // TIM1时钟
		    RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;  // TIM8时钟(仅大容量型号)
		    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;  // ADC1时钟
		    RCC->APB2ENR |= RCC_APB2ENR_ADC2EN;  // ADC2时钟
		    RCC->APB2ENR |= RCC_APB2ENR_ADC3EN;  // ADC3时钟(仅部分型号)
		    RCC->APB2ENR |= RCC_APB2ENR_EXTIEN;  // EXTI时钟
		
		    // ------------------- APB1总线外设时钟开启 -------------------
		    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;  // TIM2时钟
		    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;  // TIM3时钟
		    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;  // TIM4时钟
		    RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;  // TIM5时钟(仅大容量型号)
		    RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;  // TIM6时钟
		    RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;  // TIM7时钟
		    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;// USART2时钟
		    RCC->APB1ENR |= RCC_APB1ENR_USART3EN;// USART3时钟
		    RCC->APB1ENR |= RCC_APB1ENR_UART4EN; // UART4时钟(仅部分型号)
		    RCC->APB1ENR |= RCC_APB1ENR_UART5EN; // UART5时钟(仅部分型号)
		    RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;  // SPI2时钟
		    RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;  // SPI3时钟(仅大容量型号)
		    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;  // I2C1时钟
		    RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;  // I2C2时钟(仅部分型号)
		    RCC->APB1ENR |= RCC_APB1ENR_USBEN;   // USB时钟
		    RCC->APB1ENR |= RCC_APB1ENR_CANEN;   // CAN时钟(仅部分型号)
		    RCC->APB1ENR |= RCC_APB1ENR_PWREN;   // PWR电源管理时钟
		    RCC->APB1ENR |= RCC_APB1ENR_DACEN;   // DAC时钟(仅部分型号)
		}
		
		// 主函数测试
		int main(void)
		{
		    SystemClock_Config_Register();  // 第一步:配置系统时钟为72MHz
		    Periph_Clock_Enable_All();      // 第二步:开启所有外设时钟
		    
		    while(1)
		    {
		        // 外设功能代码(如GPIO输出、USART收发等)
		    }
		}
相关推荐
weifengdq2 小时前
10BASE-T1S LAN8651笔记 STM32 HPM5361 LwIP测试
stm32·lwip·microchip·10base-t1s·hpm5361·lan8651
三佛科技-134163842122 小时前
FT8440E 与FT8440S-RT非隔离12V/18V 200MA开关电源芯片区别与联系?
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
同年紀2 小时前
C8051 U-EC6 keil无法连接下载器解决办法
单片机·嵌入式硬件
LCG元3 小时前
STM32项目开发:基于HC-SR04的超声波测距与倒车雷达系统
stm32·单片机·嵌入式硬件
Darth Nihilus3 小时前
Raspberry Pi Compute Module Zero Development Board开发板(四)
linux·嵌入式硬件
我不是程序猿儿3 小时前
【嵌入式】外部中断的学习小坑记录
单片机·嵌入式硬件·学习
学嵌入式的小杨同学3 小时前
STM32 进阶封神之路(十三):空气质量传感器实战 ——KQM6600 模块从协议到代码(串口通信 + 数据解析)
c++·stm32·单片机·嵌入式硬件·架构·硬件架构·嵌入式实时数据库
2302_813806223 小时前
【单片机】—— 中断
单片机·嵌入式硬件·51单片机
网易独家音乐人Mike Zhou4 小时前
【嵌入式基础】Keil自动编译脚本及环境变量配置
c语言·stm32·单片机·51单片机·嵌入式·keil