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

STM32时钟详解

[复制链接]
flyingstar 发布时间:2025-12-4 15:21
STM32时钟源介绍1. STM32的时钟源主要有:
  • 内部时钟
  • 外部时钟
  • 锁相环倍频输出时钟' s$ D$ D0 ]  }% |- \# h) I" t
    640.png
    4 Y% Q. k% A( z) f/ p. T$ T: z0 S. ]. p5 v; G
1.1 详细介绍
HSI(内部高速时钟)
  • 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入

    * Q7 R7 U' F! `0 H& C& \7 s
HSE(外部高速时钟)
  • 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。
    ' Y% d" m& i2 n' D/ h/ Z
LSI(内部低速时钟)
  • 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源

    $ c0 Z( ]& L, J. B
LSE(外部低速时钟)
  • 通常外接32.768MHZ晶振提供给RTC
    % {' a* \8 W) r  U  C3 K
PLL(锁相环)
  • 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。

    / u% Q  t- e! J
MCO(时钟输出管脚)
  • 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源

    - O, Z  ~* z- Q; e
2. 标准库的时钟配置2.1 stm32启动文件
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
      Reset_Handler   PROC& g2 V* r9 f4 v* h0 K* r; t8 L; G5 a
            EXPORT  Reset_Handler    [WEAK]. _- V, u! V" r- m& X
            IMPORT  __main2 z, x# ?5 D+ I+ e6 L
            IMPORT  SystemInit
1 z4 G$ C/ Q' S% X            LDR     R0, =SystemInit
: o% L5 i. r7 x2 N7 `& _& @            BLX     R0               " J/ ?4 l3 j& A4 x: @
            LDR     R0, =__main) T3 Z; e9 a, u; Q) r' \; \
            BX      R0
0 h1 I6 j. g" ]/ f            ENDP0 j2 R  ]6 U! r2 [, d$ T4 Q$ F" w
通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。
2.2 SystemInit函数详解void SystemInit (void), k4 ^' Z: P) ]3 c$ R( G4 ?
{
9 j- _( @& L  `: ~" k2 d  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */9 _0 C. j& ?+ w9 J, d/ ~& b1 b! Z
  /* Set HSION bit */
6 j( S  b( X4 H  u# v  RCC->CR |= (uint32_t)0x00000001;
$ H2 p5 U; C8 E" |9 i3 C- D9 b& K: m+ }
  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
) g; W, G& {* E! C5 @* q5 H#ifndef STM32F10X_CL
: A+ `4 o6 r/ t: ^! y  RCC->CFGR &= (uint32_t)0xF8FF0000;
5 U1 U: M' u0 e#else
/ H' D! P. {5 Y# y8 I  RCC->CFGR &= (uint32_t)0xF0FF0000;  m2 w5 a+ p. ]  E
#endif /* STM32F10X_CL */   . P) h' R0 X) F. q" d/ Q. \' t( G6 Z
9 v' D+ J, |; f& ?9 D
  /* Reset HSEON, CSSON and PLLON bits */
# p$ g* G, j% @, s9 y# y  RCC->CR &= (uint32_t)0xFEF6FFFF;/ z7 `; d$ {& Z2 L, e2 |0 N

9 p) J% ~  D: l( v2 [  /* Reset HSEBYP bit */
# w' J1 s2 i7 x! y! L1 Q  RCC->CR &= (uint32_t)0xFFFBFFFF;
0 s5 b7 V" q. }+ g
; @9 `! ]7 B! }1 g* G: n  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
* Q; [/ Y3 {) W: g5 t# f  RCC->CFGR &= (uint32_t)0xFF80FFFF;8 N; W% n3 t; D1 z7 I+ _( O2 Y

, \( }3 `& e) Q1 t- R  ?: ]#ifdef STM32F10X_CL
; o9 n0 Y7 n; C3 K) |8 K+ {9 r1 v  /* Reset PLL2ON and PLL3ON bits */
6 a+ m4 Z, ~7 R( L' O  K% w  RCC->CR &= (uint32_t)0xEBFFFFFF;
4 H: w( b1 y1 b; j: [0 u
2 a- ]' r, E0 \3 |$ e4 ~  /* Disable all interrupts and clear pending bits  */
% ~* {) @2 u& |1 Y4 N% [, H5 E  RCC->CIR = 0x00FF0000;
' E; C% _! m7 _6 K1 ~
+ e! [8 v% S. w* n" k  /* Reset CFGR2 register */
: c1 ], G( F6 I+ H# \8 z, t8 p  RCC->CFGR2 = 0x00000000;
4 k1 z+ [# T' l2 j#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)  u! D! t8 i# c6 L9 t% l
  /* Disable all interrupts and clear pending bits  */7 N6 d) \, p9 g! u* d
  RCC->CIR = 0x009F0000;& s3 h$ L* A7 E1 O5 N7 A

! G+ S% W: `4 _. H# l8 Q3 H: i  /* Reset CFGR2 register */
+ c9 F2 q+ A0 A7 k) Q$ n  RCC->CFGR2 = 0x00000000;      ; Z  s, D& y4 f2 ?, Z* z& W0 C
#else
' a) N; B8 r4 m3 X) C2 l  /* Disable all interrupts and clear pending bits  */
$ ~9 G% }5 ]9 t1 B. k% D1 i  RCC->CIR = 0x009F0000;/ O9 b& J3 B4 b" `& H) G
#endif /* STM32F10X_CL */% X* J( u4 B. D" f9 i
# s( `" E- t. [  W+ \3 p- [* Z' m
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
4 \# D) E' Z. R  #ifdef DATA_IN_ExtSRAM
9 i. [7 p& O: R5 V' i    SystemInit_ExtMemCtl();
6 E2 j5 ^! ?; k. E/ D3 f  #endif /* DATA_IN_ExtSRAM */7 g. I; [1 r3 _; [
#endif . {9 y5 s  q9 h8 f, q2 X. a- _, }/ m
: e3 o: |& o) l, P: H' C
  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  J4 a. Y& S6 r; L3 a  /* Configure the Flash Latency cycles and enable prefetch buffer */
4 L( E, ?' s( a7 t2 D. q  SetSysClock();  V& V4 U& a8 y3 p6 s9 e7 J% e4 D
) V' i) R5 C% f6 R6 _+ p
#ifdef VECT_TAB_SRAM
, i0 O" R- A' x0 K+ e  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */) v7 P6 H" Y1 {3 `( W; c
#else3 K; g6 s6 U* y. q% f
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
2 k) V4 K8 ?8 G# C, g#endif ) R+ v/ x# E/ V3 K% v/ R
}
* g$ O7 f* I1 V2 J打开内部8M时钟RCC->CR |= (uint32_t)0x00000001
( f# L( o0 G1 m8 R4 }- {
通过查看寄存器手册可知,这段代码为打开内部8M时钟。
, L( F  J5 [# {( Z- r
微信图片_2025-12-04_151917_365.png
4 w8 j* ]' ^& b: e/ A& \设置时钟配置寄存器#ifndef STM32F10X_CL
* Y# ^% R) `- z$ e( ^  RCC->CFGR &= (uint32_t)0xF8FF0000;
* n2 w0 `! |  W% m; p5 f' i, G#else
& W; q6 ?6 J9 G: z' y  RCC->CFGR &= (uint32_t)0xF0FF0000;
5 X  M9 D0 W5 \#endif /* STM32F10X_CL */   $ _+ ^: K  B8 P$ u0 s! i# |
对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。
后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。
2.3 SetSysClock()函数详解static void SetSysClock(void)
3 J* Q$ f3 |4 a, w6 V
{
7 d" \5 {# y5 Y; B1 A* E7 T#ifdef SYSCLK_FREQ_HSE7 i9 u. z/ r" x& P4 U6 P/ W: Q
  SetSysClockToHSE();
  j$ i% S# X5 L3 Z#elif defined SYSCLK_FREQ_24MHz7 Y% F) H7 K/ g7 I
  SetSysClockTo24();
; a- V% S/ H; o0 C1 L4 J$ e#elif defined SYSCLK_FREQ_36MHz
- G8 J1 ]  F" s4 m+ t- m  SetSysClockTo36();
. J, C- W  q; B# r! @#elif defined SYSCLK_FREQ_48MHz
  p8 X- d7 f+ b# w8 J  SetSysClockTo48();
0 z6 B1 R* W/ [#elif defined SYSCLK_FREQ_56MHz& ?2 l8 I! V, I9 O+ U
  SetSysClockTo56();  
2 l5 ?7 k( P/ R4 ^  _#elif defined SYSCLK_FREQ_72MHz, b7 j3 Q: E, a- B1 ^
  SetSysClockTo72();7 U* j8 O/ }; t( S1 C
#endif
5 n, P# H" I4 k7 f3 q; \}* i$ [7 c* A- P/ L
system_stm32f10x.c文件中会根据芯片的型号定义对应的宏
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
+ l% u6 l% h3 x7 V) a- @- o/ i- U/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
# |) Y; k0 P  x0 a3 K( Z9 S) g #define SYSCLK_FREQ_24MHz  24000000- z& R- x) |4 F7 v# A7 i& z, v7 F
#else  W4 A' W; a! q: G! N. p
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
4 a. i8 s  v3 Q( Y- q/* #define SYSCLK_FREQ_24MHz  24000000 */
, v; Y  Q5 ~! S( ~% r+ C/* #define SYSCLK_FREQ_36MHz  36000000 */
: r! W" F! Y' g' p. I/* #define SYSCLK_FREQ_48MHz  48000000 */
7 I, E1 N5 i# \9 o0 X$ `$ i% Y0 }/* #define SYSCLK_FREQ_56MHz  56000000 */4 {9 y! S. P( [# Y! F3 B" u" }7 n
#define SYSCLK_FREQ_72MHz  72000000/ E! D; [6 D" w. ?+ i- x
#endif* L% B) t7 G+ @0 e
3. 时钟配置函数3.1 时钟初始化配置函数void SystemInit(void);1 B5 z1 X% e4 y  U
SYSCLK(系统时钟)=72MHZ;+ j8 e4 h4 B0 M$ B6 L9 a
AHB总线时钟(HCLK=SYSCLK)=72MHZ;
, f3 @' f. G" Q6 R+ s7 k) U1 tAPB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;. B3 R6 z) i4 K- l) |
APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
  Z: {! Z7 J- _+ EPLL主时钟=72MHZ;! P- M0 I' H. P8 H& P7 v
3.2 外设时钟使能配置函数void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);; I- Z2 }* j% l" a2 o7 D
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
; A! e1 E1 z# Ovoid RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);2 }* \, G4 Y" l9 b
3.3 时钟源使能函数void RCC_HSICmd(FunctionalState NewState);
* Y2 ?% e( H* j9 M3 Cvoid RCC_LSICmd(FunctionalState NewState);
9 `6 j+ E" M+ e  |9 wvoid RCC_PLLCmd(FunctionalState NewState);
7 a  |6 f: H7 M7 L( ~% Cvoid RCC_RTCCLKCmd(FunctionalState NewState);; }) N+ J+ n5 o1 c3 p4 N
3.4 时钟源和倍频因子配置函数void RCC_HSEConfig(uint32_t RCC_HSE);
! x6 I. g1 r# U7 _void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
9 R4 G# d" Y0 m  \" f9 Lvoid RCC_HCLKConfig(uint32_t RCC_SYSCLK);- {) q. e5 W2 |# Y- x% d
void RCC_PCLK1Config(uint32_t RCC_HCLK);7 @- y+ @7 D, E+ i
void RCC_PCLK2Config(uint32_t RCC_HCLK);; m: O+ t3 F* L( @* C2 Q
3.5 外设时钟复位函数void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
8 T* Q; n7 o* B7 T1 Q" Dvoid RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);! Q- o, ?( s. V# t7 m. r+ b
3.6 自定义系统时钟void RCC_HSE_Config(u32 div,u32 pllm)# R, i2 D- |5 c! _( H- G; d0 u
{
3 ?8 C- ]; \0 c: P( G% L. ?% R    RCC_DeInit();! Z( q4 y! k4 H' V- x; S' f: B
    RCC_HSEConfig(RCC_HSE_ON);1 P/ K& |& ?  A& _% T" i$ `3 X! D
    if(RCC_WaitForHSEStartUp()==SUCCESS)# T  r! i, }& c1 w0 F
    {   & ^* W2 L8 c- l4 N! d! x. K
        RCC_HCLKConfig(RCC_SYSCLK_Div1);% y7 T! C* i& f$ F" v2 U8 [& D
        RCC_PCLK1Config(RCC_HCLK_Div2);
# N2 r/ W2 z* y0 R/ _. v& i        RCC_PCLK2Config(RCC_HCLK_Div1);
: e8 n) _+ k2 z" g) h7 U1 X        RCC_PLLConfig(div,pllm);9 N8 N; i( w. t+ O* }' i8 H, q
        RCC_PLLCmd(ENABLE);     
4 F5 n2 e6 h% H. |! H    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
" M4 G" x' w: q1 j2 Z. C3 U8 x        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK). N3 G, C5 _/ P; f9 c
    while(RCC_GetSCLKSource()!=0x08);
9 @, d2 U& P( A; @6 C1 }! ?
$ u2 z& C# U# V* V    }' e+ m' w! U2 Q8 f  \& Y
}
9 [% o, [9 a! q' F7 ^* d; `
赞 收藏 评论0 发布时间:2025-12-4 15:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版