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

STM32时钟详解

[复制链接]
flyingstar 发布时间:2025-12-4 15:21
STM32时钟源介绍1. STM32的时钟源主要有:
  • 内部时钟
  • 外部时钟
  • 锁相环倍频输出时钟
    2 z9 X$ Q1 G- w, K4 W3 h
    640.png , ?4 k2 p5 G( N- ^5 h. U9 U5 q
    8 r6 C& g( h' b, ~+ ]" Z; Q, \3 V6 w
1.1 详细介绍
HSI(内部高速时钟)
  • 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入
    * {+ K5 k1 q: [+ @9 j2 X
HSE(外部高速时钟)
  • 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。
    5 v7 z0 ]; }& N# n+ [
LSI(内部低速时钟)
  • 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源
    1 C+ c, [# x; G7 }1 p
LSE(外部低速时钟)
  • 通常外接32.768MHZ晶振提供给RTC

    ; k+ Q- U, J" f" U
PLL(锁相环)
  • 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。
    0 S5 J% O2 L! H
MCO(时钟输出管脚)
  • 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源
    9 z- Q7 A5 G. O% f" U" m: p3 A. [1 L
2. 标准库的时钟配置2.1 stm32启动文件
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
      Reset_Handler   PROC
4 @; c9 a7 ~. L- G8 w* U8 {. h$ ?            EXPORT  Reset_Handler    [WEAK]2 T( k1 S% T! E$ y
            IMPORT  __main
- d. r: f1 {0 P# Y% i4 n            IMPORT  SystemInit* _: s3 F3 T, ~! [. ]
            LDR     R0, =SystemInit
, b( K4 M$ U0 Y4 Z! R5 s& D( C            BLX     R0               0 i# n% B4 m4 y
            LDR     R0, =__main
: O7 F9 d# h; [) X1 j1 z            BX      R0; o4 r6 z/ W9 S) k2 c
            ENDP
3 }# L: f6 b" {! R
通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。
2.2 SystemInit函数详解void SystemInit (void)
0 r& e# c2 A4 B" t0 J+ q3 O
{
* V# w7 b+ b+ C5 Z" S+ b( n' e  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */' i7 S# S3 K/ [1 j. {& z
  /* Set HSION bit */; f# F# m! n  \6 l3 j
  RCC->CR |= (uint32_t)0x00000001;5 H* x' H, I, n; ~9 \" r$ N. A& k
5 E, z( Q( I! B1 p3 K& P( \
  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
4 |6 P& j# ]9 p# ~5 _& u2 u4 @' S( s- W#ifndef STM32F10X_CL- X- H8 p' S9 ?- t: s
  RCC->CFGR &= (uint32_t)0xF8FF0000;
1 S) T% g( W) G- I4 y#else6 u: ?  u( X, H7 k# n
  RCC->CFGR &= (uint32_t)0xF0FF0000;
' q5 q3 C% L0 K6 T/ ]3 j+ Y#endif /* STM32F10X_CL */   * K7 N* a6 G) N! P9 a& Y
, T: O4 _- Z0 B% W" X, u$ _
  /* Reset HSEON, CSSON and PLLON bits */
  M7 z9 l' H% T. x/ h  RCC->CR &= (uint32_t)0xFEF6FFFF;' P. B+ ^$ V2 m' b' o

1 t/ Z+ ]+ w/ d7 e9 [; V/ N  /* Reset HSEBYP bit */8 G9 }* U' z: ^& i
  RCC->CR &= (uint32_t)0xFFFBFFFF;
- D0 o- j' E. Y+ S
8 b& M0 }  l% z  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */; X' D3 s" r6 Y2 q
  RCC->CFGR &= (uint32_t)0xFF80FFFF;! q, w; d# Q/ J. v" N; B
, e! Q1 V1 }2 w4 o, V& Y/ l. }
#ifdef STM32F10X_CL6 a8 u; ^" R3 D- q6 q% @+ v$ v
  /* Reset PLL2ON and PLL3ON bits */
- X, W' t" H/ z( o3 P6 R7 d  RCC->CR &= (uint32_t)0xEBFFFFFF;
9 L- \  |" ?0 v* u% o5 C/ y
* t. ]8 q1 W# U. }  /* Disable all interrupts and clear pending bits  */
) O/ `9 D- @% {4 A3 Z" s  RCC->CIR = 0x00FF0000;; ~' C( x( @% ]0 O
0 f1 J8 b+ M$ w
  /* Reset CFGR2 register */7 k1 ^; U: O: u  E. {' z4 M  _
  RCC->CFGR2 = 0x00000000;8 @, i2 V' j; Z6 |
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
& e3 R* P1 {4 m8 I  /* Disable all interrupts and clear pending bits  */3 \# U  F1 D6 a  l8 E  }/ L% O
  RCC->CIR = 0x009F0000;& O. O8 E6 M0 b# n
# `/ K' S( ?! t1 S) k* l. [& n
  /* Reset CFGR2 register */8 V3 \, V* X& f
  RCC->CFGR2 = 0x00000000;      
" @4 z$ T9 X7 p3 j# N7 p& @* \#else
0 J5 \7 [& }0 E9 k" H4 ^7 Z- t3 L7 E  /* Disable all interrupts and clear pending bits  */! ~$ U! k) [* V. \0 {6 ^7 q! F
  RCC->CIR = 0x009F0000;1 z* C/ ?) @$ o) Z% d' z9 H
#endif /* STM32F10X_CL */# Z4 ~! O% w# R1 Z
2 @9 r5 x6 w8 ^! X% {! |# J
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)# `6 i% w- D, X1 w1 b9 f
  #ifdef DATA_IN_ExtSRAM9 f$ `) [( [# Q+ h( r: u  d- P3 N$ p
    SystemInit_ExtMemCtl(); ' v+ z7 Y+ ?8 A% _
  #endif /* DATA_IN_ExtSRAM */8 Q' f! g8 h; ?% K  a
#endif
) v& d! q' f5 |  l9 f, \' ]5 D  Y. l" h4 e$ r
  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/ p8 P1 a& ]( a0 i" g- c0 @! v: J- f  /* Configure the Flash Latency cycles and enable prefetch buffer */# e& b) v& j& e
  SetSysClock();% Y  S1 X8 ]' O: R  v

9 d$ {% e& H1 j6 L6 d#ifdef VECT_TAB_SRAM
: l! ^) l6 p! A, w$ Q$ Q& @  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */1 i: L' Q5 ?0 ~
#else
+ n+ G0 M& t. y$ C. @  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */: X4 _, [3 H8 K2 O# M
#endif 9 U" B& q$ e1 P( G" D
}/ c8 j. H& m* d# S' p& v7 m4 n3 p
打开内部8M时钟RCC->CR |= (uint32_t)0x00000001' |7 l) n4 H# ?$ }" V
通过查看寄存器手册可知,这段代码为打开内部8M时钟。
* U4 b0 h. ~, o0 }' v3 E# r, X
微信图片_2025-12-04_151917_365.png
6 U! Z1 Q, c) C% y: L设置时钟配置寄存器#ifndef STM32F10X_CL( P7 t" w: C& R# p
  RCC->CFGR &= (uint32_t)0xF8FF0000;; I" y+ c3 S4 x' r* M
#else
5 y8 N; {) [$ X4 d# I9 T- G0 q  RCC->CFGR &= (uint32_t)0xF0FF0000;
! Z% F+ J) M0 U/ P* r#endif /* STM32F10X_CL */   
  g; M% ]% x. W& k& g
对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。
后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。
2.3 SetSysClock()函数详解static void SetSysClock(void)6 E$ {- F: j1 W' b0 [0 Q
{- n' {) Q! g, H$ j3 w) L7 [
#ifdef SYSCLK_FREQ_HSE
. u6 [" t& a8 k, X7 j4 H9 ]3 K  SetSysClockToHSE();5 y# \; m: ^: Q0 y" T
#elif defined SYSCLK_FREQ_24MHz% c( G0 A5 Y4 A' {* v) i( S9 }- \
  SetSysClockTo24();! L4 D& }" L2 g4 l* u4 E! `
#elif defined SYSCLK_FREQ_36MHz6 M( p8 v/ }" c) d( o( T
  SetSysClockTo36();
7 l. v1 J& j6 a! J: C9 ~/ a/ r#elif defined SYSCLK_FREQ_48MHz' P" f& T) s6 l
  SetSysClockTo48();
+ [. z! X$ t' U3 x#elif defined SYSCLK_FREQ_56MHz
* ^- x! v5 W. [9 P3 e  SetSysClockTo56();  $ h  F& k3 f8 ]) W( K
#elif defined SYSCLK_FREQ_72MHz+ v$ D1 E  v9 r- g
  SetSysClockTo72();- ^/ t" e7 n. E! w
#endif
7 S- C4 k- ^8 p& P- D# f}
1 o% ~) l' c+ K( m% f0 @
system_stm32f10x.c文件中会根据芯片的型号定义对应的宏
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
. C2 Z7 y4 x* K2 k/* #define SYSCLK_FREQ_HSE    HSE_VALUE *// F! j4 h8 A% w# o
#define SYSCLK_FREQ_24MHz  24000000
+ R; k3 s; W4 O( t#else; k7 c. f4 K5 v" u; t" h3 v
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */+ S, r$ ?3 z  I3 Q( \
/* #define SYSCLK_FREQ_24MHz  24000000 */ ( s* e: E( J* D8 f' A3 p
/* #define SYSCLK_FREQ_36MHz  36000000 */: B: f* H& d5 L6 K
/* #define SYSCLK_FREQ_48MHz  48000000 */, E9 n& O) `1 B
/* #define SYSCLK_FREQ_56MHz  56000000 */5 R7 ]  U9 `0 c4 I2 @' m4 P
#define SYSCLK_FREQ_72MHz  72000000- r/ i7 T7 k; ?6 r
#endif
7 B8 @, w9 o; _9 l, k0 E3. 时钟配置函数3.1 时钟初始化配置函数void SystemInit(void);
6 q+ Z7 ?/ K. T6 S; vSYSCLK(系统时钟)=72MHZ;5 O0 U) ~2 k- ]5 @9 z+ \
AHB总线时钟(HCLK=SYSCLK)=72MHZ;
5 Q' f: x5 y2 s/ EAPB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;. q) Z" `* }1 Z/ I8 M
APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
2 ]! B0 P' }9 m, [6 z$ x: o: A5 rPLL主时钟=72MHZ;+ w, I, r/ A9 u+ i. d
3.2 外设时钟使能配置函数void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);6 n5 _! ?+ Z! O0 F- X
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);6 s! Q. H6 J, f. Z# J! P
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
8 Q. {/ Z* _8 Z3.3 时钟源使能函数void RCC_HSICmd(FunctionalState NewState);
0 @, u+ }5 ^) V3 mvoid RCC_LSICmd(FunctionalState NewState);; j# T1 s/ `# X, m) W
void RCC_PLLCmd(FunctionalState NewState);
7 d4 X8 g# f$ n  A+ X+ N) }void RCC_RTCCLKCmd(FunctionalState NewState);. c8 P$ O& A- J- Z2 i4 f, X
3.4 时钟源和倍频因子配置函数void RCC_HSEConfig(uint32_t RCC_HSE);
: @+ w/ @- b. \, Tvoid RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
9 |* h9 E. e9 P7 Z9 K2 _void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
% V3 i% D( j0 j, M/ J( K0 cvoid RCC_PCLK1Config(uint32_t RCC_HCLK);
  a- o: R! v3 b0 lvoid RCC_PCLK2Config(uint32_t RCC_HCLK);) ?/ p/ X5 m+ y# L; l5 w5 W/ d
3.5 外设时钟复位函数void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);" i& j" [4 K! t0 _. V8 K& ~
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);4 }" Y. A& H+ k% ^
3.6 自定义系统时钟void RCC_HSE_Config(u32 div,u32 pllm): ^) P1 D2 s% Y3 H
{5 t  ^% H. X' X4 W! H
    RCC_DeInit();1 [! D# W; E) v3 ?! o
    RCC_HSEConfig(RCC_HSE_ON);
1 {- S: [! O+ R  T  z    if(RCC_WaitForHSEStartUp()==SUCCESS)4 Y  W0 N+ ]( o; b' b+ f
    {   
0 [8 B- w, _& ]3 l  ]0 w        RCC_HCLKConfig(RCC_SYSCLK_Div1);
. E0 e: Z( o" o# G8 Z        RCC_PCLK1Config(RCC_HCLK_Div2);, s/ i& ^4 t, F& L. H
        RCC_PCLK2Config(RCC_HCLK_Div1);
6 Z* L2 J, u9 S0 t. z0 V6 g        RCC_PLLConfig(div,pllm);
( V5 C8 k* n5 d3 j+ q( ~1 g        RCC_PLLCmd(ENABLE);     
2 S# G8 Z! P" t# Z    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)0 y* H6 I4 J, p+ e5 C
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)3 ?: B  G4 i/ c! Q% u
    while(RCC_GetSCLKSource()!=0x08);5 k; d7 K8 a1 r7 q# ~0 |/ k
7 x9 S- C) y( F( Z7 O
    }
; ~# l& M0 F* H# w% e}. X, W) U% K) M6 \, p# Z/ L! q
收藏 评论0 发布时间:2025-12-4 15:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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