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

STM32时钟详解

[复制链接]
flyingstar 发布时间:2025-12-4 15:21
STM32时钟源介绍1. STM32的时钟源主要有:
  • 内部时钟
  • 外部时钟
  • 锁相环倍频输出时钟
    6 ]; n2 x) R! b% A0 j# U6 I
    640.png
    1 b. }- G( P& n$ Q& x. ?/ u4 \* g- H
1.1 详细介绍
HSI(内部高速时钟)
  • 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入
      b' G! w- ~5 k
HSE(外部高速时钟)
  • 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。

    5 L) a( M' ?8 |1 y
LSI(内部低速时钟)
  • 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源
      `# l5 l' y) C. n1 s7 x
LSE(外部低速时钟)
  • 通常外接32.768MHZ晶振提供给RTC

    6 g! O3 k( h1 P3 g: O( }) O2 o
PLL(锁相环)
  • 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。

    + H! P: M& y6 i  U' {7 S6 {# X/ M
MCO(时钟输出管脚)
  • 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源

    , p- M0 C& E' h% A0 ?
2. 标准库的时钟配置2.1 stm32启动文件
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
      Reset_Handler   PROC
% V; r" B( l" \+ x' E2 ?            EXPORT  Reset_Handler    [WEAK]
& J% u5 \" l3 W2 p/ z# V            IMPORT  __main8 o% a# U0 b; \% d& i
            IMPORT  SystemInit
8 o* [; e* z2 }1 b' D* E, `            LDR     R0, =SystemInit3 I* q7 @8 T$ l  Q2 U. l2 O: Y
            BLX     R0               : S& \( {. ~+ M, L! v
            LDR     R0, =__main+ q' O# U* F3 I* ]: c
            BX      R0
4 h  e( k8 M. N3 m( _8 |; |" N            ENDP, F' H8 _3 a  N) A8 i) h$ P% N9 o
通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。
2.2 SystemInit函数详解void SystemInit (void)
# i0 p: F. o" ~! ?  M8 E) e
{( S0 h9 r: {% l/ }. \
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */" ~- x, a5 i9 B  [: v3 }
  /* Set HSION bit */
9 h# R7 Q: I- @* }% u* K5 P  RCC->CR |= (uint32_t)0x00000001;, H7 h' r% Z6 o8 c. w

! K. j- ?/ p- U: J  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */9 P0 B# A" \& V% E% M) v) q
#ifndef STM32F10X_CL
: `9 b0 I  `5 U  RCC->CFGR &= (uint32_t)0xF8FF0000;2 J! b( E+ z9 c8 z4 x( x" g: X
#else
* ^; Z" t( j+ r( _4 w$ G% I  RCC->CFGR &= (uint32_t)0xF0FF0000;
4 @3 @- s( t+ z, b! D, D#endif /* STM32F10X_CL */   
! a& \2 {4 }2 }  w) _/ p
/ P4 H: s5 |$ \, K! p  /* Reset HSEON, CSSON and PLLON bits */
; M0 @, ~8 A3 W' H; F1 R+ x. p9 A% m! j  RCC->CR &= (uint32_t)0xFEF6FFFF;
9 ~, ~' m1 ^3 s: P! g& J* [5 L
4 r8 R6 {7 @, V  a* `  /* Reset HSEBYP bit */
0 W: c3 K  w. Q  RCC->CR &= (uint32_t)0xFFFBFFFF;
0 P; G7 V: z/ \+ }8 X. W5 c
& K0 o- p* ]8 e* z  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
- E/ N/ f1 A) |# _* S2 ^2 J  RCC->CFGR &= (uint32_t)0xFF80FFFF;8 R3 m& s; x2 f" f+ r

4 a' L1 ~& Y- t- g4 l* h1 w9 d# Z& ?#ifdef STM32F10X_CL+ W$ Y( Z, A% K1 U7 P* ~3 C7 }( l  [
  /* Reset PLL2ON and PLL3ON bits */
( t; X/ ~0 U1 c' K1 J  RCC->CR &= (uint32_t)0xEBFFFFFF;
- c9 M9 ]) `( M: J( o8 X. C) c
' D. S% c& @3 E$ O# m. `  /* Disable all interrupts and clear pending bits  */
: _& u" Y! I( S' T. K) Y; D  RCC->CIR = 0x00FF0000;5 \! v5 r7 o) F" C" L

* J1 S% D4 `* j/ z  f+ d9 Q  /* Reset CFGR2 register */
9 T7 d& E, m5 L2 n  RCC->CFGR2 = 0x00000000;
( X# H& [! D/ Q# u1 }( E' H5 C#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
7 X8 V" @1 u& G6 @  /* Disable all interrupts and clear pending bits  */
3 f! `9 d7 z1 |: G( P* n( @  RCC->CIR = 0x009F0000;0 v! F& m' z6 f$ ]* f* v8 G

! y' |7 t* s% ?; X. Y  /* Reset CFGR2 register */. `0 Y% Y; T# J8 J% _: F# }
  RCC->CFGR2 = 0x00000000;      
2 x2 W! q0 `! q* x$ @8 r#else
/ Z7 v3 U0 I3 [7 w9 U9 H  /* Disable all interrupts and clear pending bits  */* E' E- ?+ K4 r+ t$ ?7 g$ a1 _" z
  RCC->CIR = 0x009F0000;( }# T" Z. N3 D! L! U
#endif /* STM32F10X_CL */; W/ m, ?/ P" S! B3 M/ Q: e- j  {) z
, `) B* a$ \) o: k& I; D
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)' T6 j4 a8 t& l( }; z/ j
  #ifdef DATA_IN_ExtSRAM: S% J3 r, L4 S
    SystemInit_ExtMemCtl();
3 A& t% G* F+ `. S5 T- K0 g  v  #endif /* DATA_IN_ExtSRAM */5 _. u/ W# d; r& g( z. d5 [9 n
#endif
( D8 V: k) g7 l) Y( y) Q( a3 }) M, ~: p
  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */) b: o9 I' T$ u8 H9 p; N3 Y
  /* Configure the Flash Latency cycles and enable prefetch buffer */& o7 t( w' F* x
  SetSysClock();" h9 ?8 ~7 q+ J, ]. s- m" J
, {7 b5 b, Q. |6 @% x
#ifdef VECT_TAB_SRAM1 b. p* h5 o- e5 m
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */: M$ q* s6 N  Z' x0 o: l( h
#else
; x2 k  n$ j% q3 ^8 Y8 S! u# `  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
. r$ s& \( q: q#endif
+ {( p0 t9 l! m3 h  |2 l% m" k}, h7 O9 A8 u/ N- S+ Z) B
打开内部8M时钟RCC->CR |= (uint32_t)0x00000001
' s! ^! ?% R+ B9 o: u' D
通过查看寄存器手册可知,这段代码为打开内部8M时钟。; \1 U0 b2 p* W- n4 O
微信图片_2025-12-04_151917_365.png ( C- K; @7 {) l- p
设置时钟配置寄存器#ifndef STM32F10X_CL
6 y( B0 E! |9 W5 e) j: H  RCC->CFGR &= (uint32_t)0xF8FF0000;% b% u) w9 e9 j0 C3 m/ b5 \
#else
5 _: b' {9 d( c( x6 R, r: H% [4 d  RCC->CFGR &= (uint32_t)0xF0FF0000;2 d4 K. R% a1 h, s$ @
#endif /* STM32F10X_CL */   * i% P1 o9 N7 |! K$ g7 V
对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。
后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。
2.3 SetSysClock()函数详解static void SetSysClock(void)4 \4 }* d+ n( S6 h. v% p
{- l6 t/ `: l# G7 S9 v4 s
#ifdef SYSCLK_FREQ_HSE
( N5 y3 x( N+ R; O. G/ \& U  SetSysClockToHSE();( l. y! H4 q4 A0 Z* M5 H8 u
#elif defined SYSCLK_FREQ_24MHz# ]3 J9 Y( {* S$ L5 B- d- M
  SetSysClockTo24();
" k: ^( \# ]3 ]/ q7 l( `6 s/ R8 g#elif defined SYSCLK_FREQ_36MHz2 E1 X; `. n! s8 S# g3 P
  SetSysClockTo36();
7 E2 `; ~# g2 s9 Z# B; r#elif defined SYSCLK_FREQ_48MHz0 F7 N! e7 \- q( F) \: y) J
  SetSysClockTo48();% j, u6 r0 {8 Z5 I4 t  I2 o
#elif defined SYSCLK_FREQ_56MHz+ u! C" @+ R8 u" l
  SetSysClockTo56();  
0 W" G4 T% }# z* Q1 {/ y+ C#elif defined SYSCLK_FREQ_72MHz, C6 T. u0 f% z: J' t7 I* ?: S' w
  SetSysClockTo72();
) ]6 a/ k  T0 ]4 W#endif! B2 E" Z, g" L) [# X% c( `- k
}' f; c- N" i7 D# l4 n: Y- c, [
system_stm32f10x.c文件中会根据芯片的型号定义对应的宏
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)7 ]( R& x; q3 `7 d
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
' R( K, f/ G0 s* X #define SYSCLK_FREQ_24MHz  24000000" J  b! {: G- m- e+ I
#else: C  Q9 t# v) t' f: W& s3 k  w* E& K
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */! ]' A% f1 I! K1 |7 W3 s
/* #define SYSCLK_FREQ_24MHz  24000000 */ & M9 H! Z6 C0 S) A1 d* ^& X; L
/* #define SYSCLK_FREQ_36MHz  36000000 */
3 a" C/ s3 D( f+ z8 E/* #define SYSCLK_FREQ_48MHz  48000000 */3 C+ _( A; M5 N- t' P
/* #define SYSCLK_FREQ_56MHz  56000000 */7 e" Y: _2 G/ s
#define SYSCLK_FREQ_72MHz  72000000
2 D6 x* j4 G; c% T  K#endif; D: t( i6 r" @8 Q
3. 时钟配置函数3.1 时钟初始化配置函数void SystemInit(void);
& W, }% P/ @4 d, I( T/ F) y4 eSYSCLK(系统时钟)=72MHZ;
3 v1 [6 b. a& \1 u8 }5 u" HAHB总线时钟(HCLK=SYSCLK)=72MHZ;
  [/ v  b  i6 C6 x4 \: GAPB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;! p4 P, G5 C0 e1 `" q' H3 F* A% r
APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;7 N; ~0 `  S. V, E1 G- a) ~, y
PLL主时钟=72MHZ;
1 O: w1 W  J  N7 c( a& S3.2 外设时钟使能配置函数void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
. c: z1 Z* V& f1 v: xvoid RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);1 t/ F3 y9 `; y1 p) [' t
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
& J( _% A2 X  U5 ^" J. K9 x4 @3.3 时钟源使能函数void RCC_HSICmd(FunctionalState NewState);
1 @: J$ p0 s8 V% g) m$ t6 t0 l: G# wvoid RCC_LSICmd(FunctionalState NewState);+ k3 x% w& d' i' O+ H- @" k. b/ y, n
void RCC_PLLCmd(FunctionalState NewState);0 p( c0 E7 F; ]0 [# C7 f) S" a
void RCC_RTCCLKCmd(FunctionalState NewState);
9 k9 F! \  C& e( v4 l% q3.4 时钟源和倍频因子配置函数void RCC_HSEConfig(uint32_t RCC_HSE);/ e% C' s( `, \: L* g
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
, Y. u8 j  U+ `, g) R% Nvoid RCC_HCLKConfig(uint32_t RCC_SYSCLK);6 n! b' |4 U" I
void RCC_PCLK1Config(uint32_t RCC_HCLK);2 O( ?0 W3 m8 w' g; p
void RCC_PCLK2Config(uint32_t RCC_HCLK);
: i( a7 ^( T2 i% u- U6 L3.5 外设时钟复位函数void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);1 ?$ c. h8 C2 c) w* [/ P" s
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
. C% n: e. v8 s# I) q3.6 自定义系统时钟void RCC_HSE_Config(u32 div,u32 pllm)
- L! k- ~% l* B
{+ q; n+ l5 B0 f; q8 N5 ]( A. u
    RCC_DeInit();2 m1 m* p% a% h3 {4 d
    RCC_HSEConfig(RCC_HSE_ON);/ ~/ {7 e/ F) H* `9 b' P% ~/ X
    if(RCC_WaitForHSEStartUp()==SUCCESS)( r( w/ v2 f% _
    {   
* Y* O: H9 U0 y  U( I% @" A+ d        RCC_HCLKConfig(RCC_SYSCLK_Div1);+ x% ?9 y: O0 [  |6 m( v
        RCC_PCLK1Config(RCC_HCLK_Div2);! [4 C* ^0 D2 ]: X$ E
        RCC_PCLK2Config(RCC_HCLK_Div1);6 b6 e" _. f# Q
        RCC_PLLConfig(div,pllm);
- A- r# e6 h9 ]0 y6 B! D6 U; r        RCC_PLLCmd(ENABLE);     
" V9 J6 X5 r4 K: y+ @2 D& O    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
/ w. f8 \% {& K$ u% ~& Z        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK), G$ K9 U& m/ E2 z% c3 K
    while(RCC_GetSCLKSource()!=0x08);5 z* x' I6 j; f

$ c' a8 q  s2 O: b9 _7 }4 q" n    }
! h6 [4 t1 S0 P; c4 B& o! ?}( U7 U/ ]# Y9 ~& Y' x  B
赞 收藏 评论0 发布时间:2025-12-4 15:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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