STM32时钟源介绍1. STM32的时钟源主要有:
HSI(内部高速时钟)
HSE(外部高速时钟)
LSI(内部低速时钟)
LSE(外部低速时钟)
PLL(锁相环)
MCO(时钟输出管脚)
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。 Reset_Handler PROCEXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit0 U* w- z# Z1 M5 {9 [& R# e8 p LDR R0, =SystemInit$ y% L+ j$ }1 i2 ?" C" _9 b$ L1 A% { BLX R0 5 s( K4 U6 T. H J3 r7 B% P LDR R0, =__main BX R0 ENDP6 x4 } [+ P r 通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。 2.2 SystemInit函数详解void SystemInit (void){ /* Reset the RCC clock configuration to the default reset state(for debug purpose) */! i7 Y+ w5 s- U0 U9 b. |0 d6 I4 j /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; & c0 |2 a& r) A1 y /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */; K$ M, q( F* w$ P) ~7 O6 z #ifndef STM32F10X_CL( L! z! z3 ~% n& A6 V- m RCC->CFGR &= (uint32_t)0xF8FF0000;& t N* U6 S- k #else RCC->CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */ ! r3 ?1 q h- |/ D' F/ h) I /* Reset HSEON, CSSON and PLLON bits */0 M6 l* u; c' ]% F. e% T RCC->CR &= (uint32_t)0xFEF6FFFF;3 z+ {; y0 ^6 t( V ( H: f1 J- I: z) ^" V1 c: Z /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; 0 z7 F# B- J# l8 @" v /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; #ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */) z4 D, `, h7 X RCC->CR &= (uint32_t)0xEBFFFFFF;3 ?- Q+ P R( k7 M* v5 q) y0 Y' Y /* Disable all interrupts and clear pending bits */' l( L8 m4 w, j% [" e" K1 X/ G RCC->CIR = 0x00FF0000; /* Reset CFGR2 register *// Y! Z2 d) ]6 }, H. ~, q1 T RCC->CFGR2 = 0x00000000;) g3 I) A1 `. D! q #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* Disable all interrupts and clear pending bits */5 m$ K* ]( y% R" R$ h RCC->CIR = 0x009F0000;' D! @, R& h5 v7 d * Q/ {) @! k7 q+ ?; D+ K7 T /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else, a2 V( M. Q) z& Z /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */ ! u% c6 {" p+ o0 Q5 M #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)$ m+ { ?0 {! o( t& a$ J; v7 ~& A& I #ifdef DATA_IN_ExtSRAM9 H) g- s5 T# J# R, J" W. h SystemInit_ExtMemCtl(); 7 G% ?) ]' d; j& h: Q" f. a+ A #endif /* DATA_IN_ExtSRAM */ #endif 9 E) G8 C [5 Z /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */; a/ D3 b% M, @( n% k SetSysClock(); , n4 }# h% G. K$ Y #ifdef VECT_TAB_SRAM* V" P4 D7 ?0 C 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. *// G6 [' k) h+ V* H3 L #endif : O! l5 R: t, v' S$ C }& l2 B4 j0 f r) q1 R: [& w 打开内部8M时钟RCC->CR |= (uint32_t)0x00000001# E5 e4 r4 w2 }8 R7 V8 U0 X7 F. J 通过查看寄存器手册可知,这段代码为打开内部8M时钟。
设置时钟配置寄存器#ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000;* ] y) t$ |7 Z: x #else RCC->CFGR &= (uint32_t)0xF0FF0000;( W( J0 n0 I# D2 S- b2 [2 P, | #endif /* STM32F10X_CL */ 5 b; j6 c. w2 F8 v( \) L* Y/ h' ~ 对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。 后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。 2.3 SetSysClock()函数详解static void SetSysClock(void)# Q' D# `+ G m{' I, C' g N; p+ n- @& ?0 h #ifdef SYSCLK_FREQ_HSE% W' U; ^2 Z7 g5 n SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36();) B; h" m% W( V6 I, C* N #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48();# j* u. J; E1 V0 E: O6 `* t$ r& j* E #elif defined SYSCLK_FREQ_56MHz$ k- u( R5 b/ ^* _* L SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); #endif }1 Z) Y$ }- Q1 _9 e0 k1 O" R" p system_stm32f10x.c文件中会根据芯片的型号定义对应的宏 #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)! |. J+ E' Y9 I7 b7 l/* #define SYSCLK_FREQ_HSE HSE_VALUE */ #define SYSCLK_FREQ_24MHz 24000000 #else f5 F% L; w9 y8 C /* #define SYSCLK_FREQ_HSE HSE_VALUE */3 q! b; i! p I- w0 d5 w /* #define SYSCLK_FREQ_24MHz 24000000 */ 7 \+ d. h4 N. H2 Y# Q2 T1 M /* #define SYSCLK_FREQ_36MHz 36000000 */ /* #define SYSCLK_FREQ_48MHz 48000000 */# {& l2 D; ~! w3 K6 A% a& c /* #define SYSCLK_FREQ_56MHz 56000000 */! C2 p+ x0 B" m: W #define SYSCLK_FREQ_72MHz 72000000+ f( B ?5 o* F #endif 3. 时钟配置函数3.1 时钟初始化配置函数void SystemInit(void);. d _: m$ F3 O1 C( q SYSCLK(系统时钟)=72MHZ;" d. w$ w) ~5 ~0 S& n3 m( W) x AHB总线时钟(HCLK=SYSCLK)=72MHZ; APB1总线时钟(PCLK1=SYSCLK/2)=36MHZ; APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ; PLL主时钟=72MHZ; 3.2 外设时钟使能配置函数void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);, o9 r+ P: K ]6 m void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); 3.3 时钟源使能函数void RCC_HSICmd(FunctionalState NewState); void RCC_LSICmd(FunctionalState NewState); void RCC_PLLCmd(FunctionalState NewState); void RCC_RTCCLKCmd(FunctionalState NewState); 3.4 时钟源和倍频因子配置函数void RCC_HSEConfig(uint32_t RCC_HSE);0 g% _- {/ C# X$ n( c void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_PCLK1Config(uint32_t RCC_HCLK); void RCC_PCLK2Config(uint32_t RCC_HCLK); 3.5 外设时钟复位函数void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);3 c9 _$ A6 F, w* ^6 i void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); D N& O! U8 |3 T0 F 3.6 自定义系统时钟void RCC_HSE_Config(u32 div,u32 pllm)! {1 }5 r T: N& @& |7 s { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); if(RCC_WaitForHSEStartUp()==SUCCESS) { 2 t, v/ Q1 Q0 H; Q RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PCLK2Config(RCC_HCLK_Div1);& _$ L2 G m( L' r9 a1 B RCC_PLLConfig(div,pllm);/ z' Y' [$ D) C& H8 P RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET) RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)7 `! f: k: b6 o! J5 H! }; g while(RCC_GetSCLKSource()!=0x08);8 U# x S3 |: V }6 i9 _" \1 _+ [ }/ c! I8 O" ~- D7 h( j7 C% _9 q8 N |
STM32L562DK探索板——串口通讯测试成功
STM32L562DK探索板——再试串口通讯仍不成
实战经验 | 基于STM32G0B1的全桥移相+同步整流PWM解决方案
STM32L562DK探索板——串口通讯的再测试
STM32L562DK探索板——串口通讯的测试
STM32L562DK探索板——运动传感器测试
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
STM32L562DK探索板——Audio Play的再了解
微信公众号
手机版