找回密码
 注册
关于网站域名变更的通知
查看: 713|回复: 2
打印 上一主题 下一主题

STM32入门-STM32时钟系统,时钟初始化配置函数

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-9-3 15:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
  在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:
, Y8 B' P4 P# I- h+ r  void SystemInit (void)9 E5 _- \) g( [
  {" H9 l! `" o6 n/ e& s0 V* _
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) /
. o' c9 t2 p5 v  / Set HSION bit /7 j( c' M* L' y' |8 a/ h
  RCC->CR |= (uint32_t)0x00000001;
3 ^9 A- v2 L; L' ?: ?, [! R* m  / Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits /
" t& ^3 U" f* e% y+ x, |. ^  #IFndef STM32F10X_CL
3 I: I* Y/ q0 g! G$ ^. l2 R" g  RCC->CFGR &= (uint32_t)0xF8FF0000;
7 W" W; \) `% f  #else  H! A" i# ^0 s2 N4 H8 q. Y% {
  RCC->CFGR &= (uint32_t)0xF0FF0000;. G; G2 |$ \6 v+ q) ?! K
  #endif / STM32F10X_CL /) a, e$ [2 X, f: J# w; w; M# X
  / Reset HSEON, CSSON and PLLON bits /: N# _5 K0 w  |4 q9 }; R3 ~4 E
  RCC->CR &= (uint32_t)0xFEF6FFFF;+ y" a, H2 D2 P
  / Reset HSEBYP bit // d$ y( X! h% c9 J7 C
  RCC->CR &= (uint32_t)0xFFFBFFFF;
8 l7 r+ ~% S- y% d7 ?  / Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits /
0 D" a1 l3 ]# f3 \  RCC->CFGR &= (uint32_t)0xFF80FFFF;
( }; S" V; E1 C2 L  D  #ifdef STM32F10X_CL4 t1 o7 R" r. t2 W
  / Reset PLL2ON and PLL3ON bits */, n) F" |. v8 s. D8 t
  RCC->CR &= (uint32_t)0xEBFFFFFF;' s. R9 E( Z. h
  /* Disable all interrupts and clear pending bits /
9 X$ K! ^& L: `' Y* S' q  RCC->CIR = 0x00FF0000;  ^9 r- Y$ v/ [
  / Reset CFGR2 register /: W9 n4 n0 e& u+ E4 l
  RCC->CFGR2 = 0x00000000;
) r# C6 V: b, Y  #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined' A: F. e3 t' h
  STM32F10X_HD_VL)
% Z1 x5 D: S( p6 l! D: C$ Z- q  / Disable all interrupts and clear pending bits /
  ~% R4 S7 C7 N4 d" j  RCC->CIR = 0x009F0000;* Y; w0 X1 j  a3 X* ~
  / Reset CFGR2 register /" ?2 H! s  j9 _- j
  RCC->CFGR2 = 0x00000000;5 K0 k* }' T3 e* W9 J0 x9 y) J  i9 k
  #else
$ G; v8 ?8 J. O% W+ ~- h  / Disable all interrupts and clear pending bits /
9 t/ M2 o0 q3 j: `  RCC->CIR = 0x009F0000;
8 ]: m, U7 P' R  #endif / STM32F10X_CL /8 q& ]+ w6 g  @* e; S
  #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined/ ?2 [% {9 C+ _
  STM32F10X_HD_VL)
( Q% U/ R8 p( {9 Z  #ifdef DATA_IN_ExtSRAM9 Q1 \/ n- w7 ?
  SystemInit_ExtMEMCtl();3 r4 w! p# J- w/ Q. @
  #endif / DATA_IN_ExtSRAM /
  O7 Y: b4 J5 x, _  #endif# E# Q. F9 v- S) p( r
  / Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers /4 _+ G% \, I- P
  / Configure the Flash Latency cycles and enable prefetch buffer /
' G5 g5 X. E; ~: b' R) ]9 X' l  SetSysClock();; g, ]! x" r7 u0 E' s. u3 T
  #ifdef VECT_TAB_SRAM2 \2 }; A9 ]3 {2 T; V+ b
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in Internal SRAM. /. H8 g. }% ^$ K! f' }$ y
  #else) n8 I9 H. ^$ ]  K$ F. }
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in
7 @  q* r! i7 d0 _/ @' ]  Internal FLASH. */0 G1 B* H; w9 M' x9 g
  #endif$ _+ m8 z! V$ K( C0 O
  }
* k/ ?9 C' U& ?! O7 h  SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:
; f% Z* ~- {% K  static void SetSysClock(void)
6 `3 J& Q  D" h2 r$ S; ?  {
8 i8 T5 T0 o- O  O0 N" T: k  #ifdef SYSCLK_FREQ_HSE0 {+ _1 Q0 d0 ?
  SetSysClockToHSE();2 a, }9 y7 d# ~) ~' ^, S4 A& T8 }/ k
  #elif defined SYSCLK_FREQ_24MHz6 k8 x; f# a9 i+ j
  SetSysClockTo24();8 Z  ]- _% L; a% }$ T4 `% l0 p) ]7 Z
  #elif defined SYSCLK_FREQ_36MHz
! z; v7 }7 x- `4 q  D$ B/ S  SetSysClockTo36();! l6 i5 K) V0 l9 i
  #elif defined SYSCLK_FREQ_48MHz, i- Y! m; I( p% |* ^& D# M' o
  SetSysClockTo48();7 o9 T/ Z, t$ _0 S4 M
  #elif defined SYSCLK_FREQ_56MHz
+ K$ [" ~: A7 z  SetSysClockTo56();9 [4 I6 o9 K) {$ \
  #elif defined SYSCLK_FREQ_72MHz
+ ^5 n: h* M0 G; g$ E! o/ `( S  SetSysClockTo72();
5 r$ ]; \+ b% Y  #endif
0 z0 c$ u- H9 e  }' J7 k$ d) _; P& D+ e
  在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:/ B" A! N# ^( d8 u" T  Q1 I4 C' e
  #define SYSCLK_FREQ_72MHz 72000000
/ h2 J, `" }/ H. r2 k  x" j  如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:
- H# y7 O5 @2 w3 t$ Z8 }1 A/ R  #define SYSCLK_FREQ_36MHz 36000000
1 u. M( h* C- i! D9 o  根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:
, H" v; G* \$ ?' v- M) ]. n) o  SYSCLK(系统时钟) =72MHz; o& `" ^: P: D8 d3 B) A1 K4 b
  AHB 总线时钟(HCLK=SYSCLK) =72MHz; L2 j' G# y/ x& L5 @( q
  APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz
! w! n4 y  p0 P4 k% r) V; N  APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz
1 Q8 C! n$ ]8 z2 V  PLL 主时钟 =72MHz
* _, b2 {. ]2 [' L8 D' C  在STM32中,这些时钟值是要熟悉的。# `  n: F1 Y! B7 M: N) G

- ]0 s) j* |: F- c/ l; H( z# ], p4 I3 N
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-18 06:33 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表