STMCU小助手
发布时间:2022-7-1 13:11
|
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下: void SystemInit (void) { /* Reset the RCC clock configuration to the default reset state(for debug purpose) */2 P* ^; F! l" x8 a' r( Q /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001;% L& n- e) q8 @ v- R# F$ f /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */5 N5 o( o' V! a2 m #ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000; #else RCC->CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */ /* Reset HSEON, CSSON and PLLON bits */$ R, z2 b. P1 d9 y. j- P RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset HSEBYP bit */$ t0 T6 A. E* X% Y2 f$ Y4 U% ` RCC->CR &= (uint32_t)0xFFFBFFFF;/ ]1 [& t7 P' F ^! [1 _0 i /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; #ifdef STM32F10X_CL9 y7 Q8 v7 J' b! H$ d /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF; /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000;6 u; ^# Y0 \; d; z0 b /* Reset CFGR2 register */4 S4 t6 \9 M% i8 B RCC->CFGR2 = 0x00000000;; f( a' } A& X& g #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* Disable all interrupts and clear pending bits */% x6 @- ?1 A+ F; Y) n! Q9 ~& v RCC->CIR = 0x009F0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */2 y# w# S( A4 B #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined9 y1 T6 d9 X! C* q STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM0 W) w" W0 J4 g$ F$ v; Y3 Y, ^ SystemInit_ExtMemCtl();5 W% O8 K# u; ~& l, }* n2 W #endif /* DATA_IN_ExtSRAM */: O! @; K: T& O. O& {* E" c9 M6 | o #endif- l! y" w* t) D! s /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */0 D* ~3 c3 }1 [ /* Configure the Flash Latency cycles and enable prefetch buffer */' ]4 _) r4 l7 T0 I SetSysClock();) \! l8 b. J' n& M: M. V: K# N# ?; F, Y #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ #else, U s' u3 V. R% n SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ #endif } 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) n, G0 ~+ M# \; {2 \ H" a' D: ?" v SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz$ p2 ?+ g- l X. m3 E5 D SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz2 F- |: E# x, x! m SetSysClockTo72();; d" \+ [+ J$ ]$ ?) a4 O& ^ #endif } 在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:' Z! R: N6 H( ~( C3 j #define SYSCLK_FREQ_72MHz 72000000 如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:& Q7 b6 e% x, e- G! H, k, Q, K7 Y | #define SYSCLK_FREQ_36MHz 36000000 根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:- | n5 }4 n7 h9 Y) [4 r% u SYSCLK(系统时钟) =72MHz AHB 总线时钟(HCLK=SYSCLK) =72MHz. s M1 x3 }; K( Y9 ], C APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz+ {0 x; u8 ?: q& q- a APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz PLL 主时钟 =72MHz 在STM32中,这些时钟值是要熟悉的。 6 ?, d; k" { ?: P |
【STM32H735G-DK 测评】STM32H735G-DK External Loder 编译和测试
《MCUBoot课程》学习笔记+从信任链原理到量产实践
Keil-MDK 在线调试设置断点的高级用法
请教下STM32N6570 怎么把分辨率改成320x240并可以全屏显示
【福利三:逢7发帖赢大礼】想要充分利用STM32H743VI片内的RAM空间(但并不顺利)
基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理
使用STM32 MCU和MPU连接PDM数字麦克风
分享STM32资料-采用 STM32U031R8 MCU 的 STM32 Nucleo-64 开发板,官方资料,数据手册等资料
好用软件推荐-TouchGFX Designer
HRTIM 指南
微信公众号
手机版