文章目录
- 一、时钟相关寄存器
-
- [ 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、配置系统时钟为72MHZ(HSE = 8MHZ晶振)](# 1、配置系统时钟为72MHZ(HSE = 8MHZ晶振))
- 2、开启外设时钟(取所需代码)
一、时钟相关寄存器
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收发等)
}
}