写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。
标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。
点击此处进入学习日记的总目录
2023.04.29
- 一、32:时钟树
- 二、32: 时钟配置
- 时钟控制寄存器(RCC_CR)
- 时钟配置寄存器(RCC_CFGR)
- 时钟中断寄存器 (RCC_CIR)
- APB2 外设复位寄存器 (RCC_APB2RSTR)
- APB1 外设复位寄存器 (RCC_APB1RSTR)
- AHB外设时钟使能寄存器 (RCC_AHBENR)
- APB2 外设时钟使能寄存器(RCC_APB2ENR)
- APB1 外设时钟使能寄存器(RCC_APB1ENR)
- 备份域控制寄存器 (RCC_BDCR)
- 控制/状态寄存器 (RCC_CSR)
一、32:时钟树
- 要了解时钟系统,就需要查看数据手册中的时钟树。以下是时钟树的基本逻辑:
- 下面是
STM32F103VET6
的时钟树与其详细解释
需要注意的是,每一个型号的处理器的时钟树都有所不同
3. 时钟控制寄存器
我们控制时钟树的办法,就是通过控制时钟树中的分频器
、开关
、与门
,来获得不同的时钟频率。
控制寄存器的方法是给RCC寄存器赋值,在程序中一般会将各种寄存器设置集中到一个结构体中。
举例说明1:
RCC->CR |= (uint32_t)0x00000001;
查看RCC_CR
寄存器
观察到代码操作为将第0位
赋值为1
所以该代码的作用为设置为内部高速时钟使能,即启动处理器内部8MHz振荡器
。
举例说明2:
RCC->CR &= (uint32_t)0xFEF6FFFF;
PLL关闭,HSE关闭,外部3-25MHz外部晶体振荡器被旁路,时钟监测器关闭。
- 锁相环
- 系统时钟
参考资料:
耗时三天,STM32精讲,原理图一遍必懂!!!
二、32: 时钟配置
- 先查看系统结构,观察所需模块对应哪一条时钟线
- RCC寄存器描述
时钟控制寄存器(RCC_CR)
时钟配置寄存器(RCC_CFGR)
时钟中断寄存器 (RCC_CIR)
APB2 外设复位寄存器 (RCC_APB2RSTR)
APB1 外设复位寄存器 (RCC_APB1RSTR)
AHB外设时钟使能寄存器 (RCC_AHBENR)
APB2 外设时钟使能寄存器(RCC_APB2ENR)
APB1 外设时钟使能寄存器(RCC_APB1ENR)
备份域控制寄存器 (RCC_BDCR)
控制/状态寄存器 (RCC_CSR)
- 实际项目例子
这是一个项目的时钟初始化代码:
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
下面是对每一句代码的详细解释:
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
该语句将RCC
寄存器的CR
(控制)寄存器的最低位(HSION
位)设置为1,以启用内部高速时钟(HSI
)。
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
根据条件编译的指令,这段代码将RCC
寄存器的CFGR
(配置)寄存器的特定位设置为默认值。具体来说,它重置了SW
(系统时钟选择)、HPRE
(AHB
预分频因子)、PPRE1
(APB1
预分频因子)、PPRE2
(APB2
预分频因子)、ADCPRE
(ADC
预分频因子)和MCO
(主时钟输出)的位。具体要设置的位与条件编译的指令相关。
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
该语句通过将RCC寄存器的CR
寄存器的HSEON位(外部高速时钟使能)、CSSON位(时钟安全系统使能)和PLLON位(锁相环使能)设置为0来重置这些位。
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
该语句通过将RCC
寄存器的CR寄存器的HSEBYP
位(外部高速时钟旁路)设置为0来重置该位。
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
该语句通过将RCC
寄存器的CFGR
寄存器的PLLSRC
位(PLL
时钟源选择)、PLLXTPRE
位(外部高速时钟预分频因子)、PLLMUL
位(锁相环倍频因子)和USBPRE/OTGFSPRE
位(USB OTG FS/SDIO
时钟预分频因子)设置为默认值,来重置这些位。
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD
_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
这一部分是根据条件编译的指令,在不同的芯片型号中进行处理。对于某些特定的型号,例如STM32F10X_CL
,该代码将RCC
寄存器的CR
寄存器的PLL2ON
位和PLL3ON
位设置为0。对于其他型号,该代码将RCC
寄存器的CIR
(中断使能)寄存器设置为0x00FF0000
,并将RCC
寄存器的CFGR2
(配置2)寄存器设置为0x00000000
。
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
这部分代码根据条件编译的指令,在某些特定的芯片型号中进行处理。如果定义了宏STM32F10X_HD
、STM32F10X_XL
或STM32F10X_HD_VL
,并且定义了宏DATA_IN_ExtSRAM
,将调用SystemInit_ExtMemCtl()
函数。这段代码用于初始化外部SRAM
控制器。
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
这行代码调用SetSysClock()
函数,用于配置系统时钟频率、HCLK
、PCLK2
和PCLK1
的预分频器,并设置Flash
的延迟周期和预取缓冲器。
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
这段代码根据条件编译的指令,将向量表(存储中断向量的表格)的偏移地址设置到系统内部的SRAM
或闪存中。根据定义的宏VECT_TAB_SRAM
,选择将向量表重定位到内部SRAM
(SRAM_BASE
)加上偏移地址(VECT_TAB_OFFSET
),或者重定位到内部闪存(FLASH_BASE
)加上偏移地址(VECT_TAB_OFFSET
)。