
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下: void SystemInit (void) {7 _8 U7 p# m; t7 v# X y0 a7 I /* Reset the RCC clock configuration to the default reset state(for debug purpose) */4 ]& Z1 D& R; q9 |$ a& Y, P /* 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; #else4 `/ Q8 o* s: b1 }3 [- [5 v& j RCC->CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */% `" J7 [ y9 L# C' X /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF;. `% ?6 Z2 f S /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */: `0 c% K* ~* ] A. N5 p# m6 r, a RCC->CFGR &= (uint32_t)0xFF80FFFF;/ {4 b O) R C4 v #ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */( \) v. W3 Z& t! M. q/ H RCC->CR &= (uint32_t)0xEBFFFFFF; . L( N. U# r: l: e J9 ] /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000;: d# b" b3 V8 D: K /* Reset CFGR2 register */3 k: [ X/ ^0 q7 Z RCC->CFGR2 = 0x00000000;5 [: G+ r* t/ D' p% P" c2 m9 G" y #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL): c, D4 e! \: i; B+ B# [& c" W. i /* Disable all interrupts and clear pending bits */9 _" a% s' c5 r P1 Z: a" D RCC->CIR = 0x009F0000;& F ?: Y4 ]; y3 s8 G& s' u /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else /* Disable all interrupts and clear pending bits */0 o: u7 L6 m7 \/ f5 c2 y RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */: O8 Z; K- p1 g; k& j( Y. f# g! | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined# X& C7 [. h* ]5 k1 p STM32F10X_HD_VL): h8 G; x" `. y4 ~8 B* R #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl();/ B: G H# I0 Y9 o- E, l #endif /* DATA_IN_ExtSRAM */ #endif2 p/ A# i/ {6 b8 t E! M+ q /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */$ P9 e! ]7 ], H 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' `: W0 y! z. z$ w6 w7 N( l Internal FLASH. */4 D: @* G) X9 |6 f7 N3 q #endif) c! a- Y+ U# S* S D0 t7 i } SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下: static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz: p0 ?& W# h! g: \9 A+ l SetSysClockTo36();( T3 T7 u7 q/ U #elif defined SYSCLK_FREQ_48MHz$ U9 I9 {; P( H$ t! k9 V1 j4 n: x SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz) m& J# ^4 t6 r SetSysClockTo56();1 f% _5 Q3 W# a' U #elif defined SYSCLK_FREQ_72MHz4 B8 h5 R: o4 G3 Q% e SetSysClockTo72(); #endif } 在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下: #define SYSCLK_FREQ_72MHz 72000000 如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:9 s1 S! o: V: H/ B #define SYSCLK_FREQ_36MHz 36000000 根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:4 }( m' N8 R [4 v: D8 w SYSCLK(系统时钟) =72MHz AHB 总线时钟(HCLK=SYSCLK) =72MHz% d9 E, [) c1 T0 I- d7 Z2 o& _) i APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz' x# ]: c: v5 s) R$ Z, h APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz' D. }4 T6 N* `3 |( V PLL 主时钟 =72MHz R. ]& o" g$ B3 M2 }; Z; ] 在STM32中,这些时钟值是要熟悉的。 |
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
刘氓兔的64位入门挑战【1】——MP257芯片下单和硬件准备
刘氓兔的64位入门挑战【0】——MP257选型
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享