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

【经验分享】STM32入门系列-STM32时钟系统,时钟初始化配置函数

[复制链接]
STMCU小助手 发布时间:2022-7-1 13:11
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:

void SystemInit (void)
: S5 f1 C$ t9 r5 q# ~9 {* [{7 _8 U7 p# m; t7 v# X  y0 a7 I
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */4 ]& Z1 D& R; q9 |$ a& Y, P
/* Set HSION bit */
" h8 l% g! W+ i2 v! K2 wRCC->CR |= (uint32_t)0x00000001;
, u& ?' S5 v' K- i) l  R4 _. {/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
2 j& ?3 D. P; Q' A/ C+ o4 p#ifndef STM32F10X_CL
# l6 Z- ]9 E; c. \, RRCC->CFGR &= (uint32_t)0xF8FF0000;
' f9 o* E& H: L; a2 \2 g#else4 `/ Q8 o* s: b1 }3 [- [5 v& j
RCC->CFGR &= (uint32_t)0xF0FF0000;
- B* C% J* y- Q* o2 \2 t#endif /* STM32F10X_CL */% `" J7 [  y9 L# C' X
/* Reset HSEON, CSSON and PLLON bits */
/ n+ c! R1 {  q6 E+ ~% C$ YRCC->CR &= (uint32_t)0xFEF6FFFF;
9 P* f% T2 |% D/* Reset HSEBYP bit */
& n2 z, B2 g, u2 r3 k+ vRCC->CR &= (uint32_t)0xFFFBFFFF;. `% ?6 Z2 f  S
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */: `0 c% K* ~* ]  A. N5 p# m6 r, a
RCC->CFGR &= (uint32_t)0xFF80FFFF;/ {4 b  O) R  C4 v
#ifdef STM32F10X_CL
8 O% `5 f% [0 F1 V2 q/* Reset PLL2ON and PLL3ON bits */( \) v. W3 Z& t! M. q/ H
RCC->CR &= (uint32_t)0xEBFFFFFF; . L( N. U# r: l: e  J9 ]
/* Disable all interrupts and clear pending bits */
% L, h+ E: R& qRCC->CIR = 0x00FF0000;: d# b" b3 V8 D: K
/* Reset CFGR2 register */3 k: [  X/ ^0 q7 Z
RCC->CFGR2 = 0x00000000;5 [: G+ r* t/ D' p% P" c2 m9 G" y
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined
) y1 y; {! |/ Y* T7 o2 P6 {" N2 jSTM32F10X_HD_VL): c, D4 e! \: i; B+ B# [& c" W. i
/* Disable all interrupts and clear pending bits */9 _" a% s' c5 r  P1 Z: a" D
RCC->CIR = 0x009F0000;& F  ?: Y4 ]; y3 s8 G& s' u
/* Reset CFGR2 register */
1 F. l* ]; c; w% R/ N3 m' [/ n- _RCC->CFGR2 = 0x00000000;
8 a5 U: t, r$ t# h; S#else
( D1 y8 V: J0 s- T1 n3 y% D8 h" T/* Disable all interrupts and clear pending bits */0 o: u7 L6 m7 \/ f5 c2 y
RCC->CIR = 0x009F0000;
2 M  @5 n) v- J( {& B0 a. T2 Y. Z4 O#endif /* STM32F10X_CL */: O8 Z; K- p1 g; k& j( Y. f# g! |
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined# X& C7 [. h* ]5 k1 p
STM32F10X_HD_VL): h8 G; x" `. y4 ~8 B* R
#ifdef DATA_IN_ExtSRAM
- u6 }7 \0 F* b) }SystemInit_ExtMemCtl();/ B: G  H# I0 Y9 o- E, l
#endif /* DATA_IN_ExtSRAM */
' r5 `; @1 U0 w' Y4 ~" I#endif2 p/ A# i/ {6 b8 t  E! M+ q
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
, f& w; c- a. K5 Y& ]$ ]/* Configure the Flash Latency cycles and enable prefetch buffer */$ P9 e! ]7 ], H
SetSysClock();
6 p! ]. z/ ^4 _& o* G# {- z. V* p#ifdef VECT_TAB_SRAM
# g+ k8 v+ {( H: a  gSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
0 ~- ~5 t5 Z* E7 ]' Z) C#else
7 T" t8 s' ^6 ?' o9 H& TSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in' `: W0 y! z. z$ w6 w7 N( l
Internal FLASH. */4 D: @* G) X9 |6 f7 N3 q
#endif) c! a- Y+ U# S* S  D0 t7 i
}

SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:

static void SetSysClock(void)
5 G9 d5 c  A  H  z9 k6 a{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz: p0 ?& W# h! g: \9 A+ l
SetSysClockTo36();( T3 T7 u7 q/ U
#elif defined SYSCLK_FREQ_48MHz$ U9 I9 {; P( H$ t! k9 V1 j4 n: x
SetSysClockTo48();
* x" i: \) ^! n1 A#elif defined SYSCLK_FREQ_56MHz) m& J# ^4 t6 r
SetSysClockTo56();1 f% _5 Q3 W# a' U
#elif defined SYSCLK_FREQ_72MHz4 B8 h5 R: o4 G3 Q% e
SetSysClockTo72();
  S$ I! d- x0 c5 P: u9 t: |0 n! H#endif
}

  在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:
4 g% N' c3 L8 A* S( s

#define SYSCLK_FREQ_72MHz 72000000
9 O& J) d5 Y/ D  [0 m

  如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:9 s1 S! o: V: H/ B

#define SYSCLK_FREQ_36MHz 36000000
& \; d6 C# n6 H  @

  根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:4 }( m' N8 R  [4 v: D8 w

SYSCLK(系统时钟) =72MHz
4 d/ T( `. I. D7 Z- C' t+ wAHB 总线时钟(HCLK=SYSCLK) =72MHz% d9 E, [) c1 T0 I- d7 Z2 o& _) i
APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz' x# ]: c: v5 s) R$ Z, h
APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz' D. }4 T6 N* `3 |( V
PLL 主时钟 =72MHz  R. ]& o" g$ B3 M2 }; Z; ]

       在STM32中,这些时钟值是要熟悉的。

8 R! ]" j) l  k5 e% h( h
收藏 评论0 发布时间:2022-7-1 13:11

举报

0个回答

所属标签

相似分享

官网相关资源

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