你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32时钟详解

[复制链接]
flyingstar 发布时间:2025-12-4 15:21
STM32时钟源介绍1. STM32的时钟源主要有:
  • 内部时钟
  • 外部时钟
  • 锁相环倍频输出时钟
    * n7 [) r/ b+ l8 P: ?
    640.png 0 U, |# v7 q9 @7 r6 N

    % N* |8 S: F& Z$ \6 q1 x' y
1.1 详细介绍
HSI(内部高速时钟)
  • 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入
    ; c6 a" w! S( \: w) F! H0 a  h* Y
HSE(外部高速时钟)
  • 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。

    ; ?( O  v2 Q8 r# G: \
LSI(内部低速时钟)
  • 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源
    " V6 o& y4 ~7 Y2 p9 l
LSE(外部低速时钟)
  • 通常外接32.768MHZ晶振提供给RTC

    - L+ X1 ?$ C! F; x5 [6 u/ A
PLL(锁相环)
  • 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。

    - L0 X! \+ F# s1 f$ D7 j0 A
MCO(时钟输出管脚)
  • 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源

    1 \1 P5 h8 K+ K) f' [
2. 标准库的时钟配置2.1 stm32启动文件
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
      Reset_Handler   PROC
% _# s2 U& s8 n& z8 T" o. n            EXPORT  Reset_Handler    [WEAK]
- h0 k! o, H/ H  z- j0 G            IMPORT  __main
4 L! ]( N3 f  Z, d; l9 f            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
' L- K1 ?: f9 M  E& k, s            BX      R0
: q2 N. ^; u1 R* l            ENDP6 x4 }  [+ P  r
通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。
2.2 SystemInit函数详解void SystemInit (void)
( L  b% R! \! h* f; ]3 A) P. g  @
{
5 W) R6 f; `+ _) ~3 A$ Q' ]; n  /* 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 */
; G# W% r8 Q8 q+ v+ [& v+ b8 u  RCC->CR |= (uint32_t)0x00000001;
& c7 \3 D7 [: V& 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
- G9 Y' E/ u: ^; ~4 [: A  RCC->CFGR &= (uint32_t)0xF0FF0000;
  H) M/ }: ~4 A4 o( b#endif /* STM32F10X_CL */   ! r3 ?1 q  h- |/ D' F/ h) I

3 m; Z+ ]; ?4 V( e, I7 v0 s& c  /* 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 */
: x- M5 V% `1 _2 T- c$ {  RCC->CR &= (uint32_t)0xFFFBFFFF;
' [" N: P% o, N3 Z' B( m% r5 o& j0 z7 F# B- J# l8 @" v
  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  x0 u! T7 C) h, q' s  RCC->CFGR &= (uint32_t)0xFF80FFFF;
% L" j) i! ~, H) F
0 t" h6 Z' R! T8 G* y( ]8 M1 a, O% T#ifdef STM32F10X_CL
9 b8 N0 v' i3 D" N% C% r% }  /* 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

4 y% \. f' s3 t  K' }( r  /* Disable all interrupts and clear pending bits  */' l( L8 m4 w, j% [" e" K1 X/ G
  RCC->CIR = 0x00FF0000;
8 K9 `1 ~/ H: R
7 k1 t2 e3 ?, K4 R  /* 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)
* h) r- q1 Z. A+ u  /* 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 */
  ^0 d( f! ?; S6 w! P  RCC->CFGR2 = 0x00000000;      
3 q1 \* ]* S; m' R8 W4 v3 W#else, a2 V( M. Q) z& Z
  /* Disable all interrupts and clear pending bits  */
+ E8 m6 G! A( t8 g* m4 S/ S1 s! H  RCC->CIR = 0x009F0000;
5 C2 L/ j( `; }- q#endif /* STM32F10X_CL */
0 o# I/ m6 R7 L% v! 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 */
  S4 _8 ~; L  B" y- n$ @- G#endif 9 E) G8 C  [5 Z

7 D; i; }1 _8 r( f" Y5 I* K  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
3 ?$ @9 [8 @; f6 ~" V! s( m  /* Configure the Flash Latency cycles and enable prefetch buffer */; a/ D3 b% M, @( n% k
  SetSysClock();
4 S) u  ~3 V+ E! c# p0 R1 S* X, 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. */
8 V3 s1 S- q# G#else
2 ^; F3 ^( y. M1 A- r  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时钟。
! l$ R  g- O' O/ A0 m) o& v, Y
微信图片_2025-12-04_151917_365.png
# x% \+ a( D$ G. U0 {7 o6 n设置时钟配置寄存器#ifndef STM32F10X_CL
2 {$ w/ Y& X8 l6 u. a: g  RCC->CFGR &= (uint32_t)0xF8FF0000;* ]  y) t$ |7 Z: x
#else
+ y4 {% N: |$ ?3 t  [* N9 N  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();
; s1 d* b! _+ F4 f0 b# v( W#elif defined SYSCLK_FREQ_24MHz
  G& ^, B- }* x; L0 q, U: Z  SetSysClockTo24();
4 x5 w0 [& j7 F' s, @# O! Z% W#elif defined SYSCLK_FREQ_36MHz
- V. W8 B: J1 W/ B  SetSysClockTo36();) B; h" m% W( V6 I, C* N
#elif defined SYSCLK_FREQ_48MHz
% U" q. T  u5 |! n, J* W  SetSysClockTo48();# j* u. J; E1 V0 E: O6 `* t$ r& j* E
#elif defined SYSCLK_FREQ_56MHz$ k- u( R5 b/ ^* _* L
  SetSysClockTo56();  
( V; V; o4 K: d#elif defined SYSCLK_FREQ_72MHz
( d* u8 |7 H7 Q$ U$ l0 x- L  SetSysClockTo72();
1 _7 S% G+ H0 ?5 I3 W7 h! R#endif
. F- w5 Z6 m9 d}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 */
0 N( x' b7 e% g5 D$ `, ^* Y1 [ #define SYSCLK_FREQ_24MHz  24000000
5 U* b3 X# b% F5 _  Y' `#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 */
" t5 h4 v* X% g7 S/* #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
8 T6 {# K, e( Z) |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;
( t* d" V: G. R) u6 CAPB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;
  V' X6 N# h9 U4 YAPB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
7 j" _( N2 I9 jPLL主时钟=72MHZ;
- {( `0 I  J. t& E2 P4 l3.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);
( c& T( Z* O# q# s3 ivoid RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
1 t# ~9 l7 I  L6 K3.3 时钟源使能函数void RCC_HSICmd(FunctionalState NewState);
0 A: h1 y& k& l* `$ N3 N* wvoid RCC_LSICmd(FunctionalState NewState);
6 h# i2 n4 F( n. Nvoid RCC_PLLCmd(FunctionalState NewState);
, J! n- z, |8 f1 n: vvoid RCC_RTCCLKCmd(FunctionalState NewState);
8 d( h' r* u% n) b3.4 时钟源和倍频因子配置函数void RCC_HSEConfig(uint32_t RCC_HSE);0 g% _- {/ C# X$ n( c
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
2 G; i- l6 g& q- w; x& o1 x' k4 pvoid RCC_HCLKConfig(uint32_t RCC_SYSCLK);
' ?/ Y! i7 g) pvoid RCC_PCLK1Config(uint32_t RCC_HCLK);
9 h( j6 w4 F) ?$ svoid RCC_PCLK2Config(uint32_t RCC_HCLK);
0 f( @+ q; R6 f! n+ L; c3 n& u3.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
{
: H$ F# U; b( Q    RCC_DeInit();
! K- |% B" V; r! X; J    RCC_HSEConfig(RCC_HSE_ON);
& w. G% o: x4 N! j    if(RCC_WaitForHSEStartUp()==SUCCESS)
" p5 G8 @5 }. q# R( o' z    {   2 t, v/ Q1 Q0 H; Q
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
8 @5 X- h4 J4 J" [' o        RCC_PCLK1Config(RCC_HCLK_Div2);
8 L/ Z( [) n9 m9 L        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);     
! _6 w! @+ y2 k! \5 w/ s; i0 ?    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  d0 i6 y2 X: u7 x        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)7 `! f: k: b6 o! J5 H! }; g
    while(RCC_GetSCLKSource()!=0x08);8 U# x  S3 |: V

! E5 n3 L$ i/ U  W' I% @( E+ s8 q    }6 i9 _" \1 _+ [
}/ c! I8 O" ~- D7 h( j7 C% _9 q8 N
收藏 评论0 发布时间:2025-12-4 15:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版