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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
  在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:
6 O: v& J0 `. J" P' @3 r& w  void SystemInit (void)* O9 S7 C- ~4 [; x, i
  {
! H7 B2 b4 [# o/ W( B5 m$ N+ F  /* Reset the RCC clock configuration to the default reset state(for debug purpose) /0 a; T  S3 y' P' _& n# D6 }
  / Set HSION bit /
$ ?& Z3 c3 f' ?8 A8 Y4 Y5 f  RCC->CR |= (uint32_t)0x00000001;
8 r: r; [: p5 u' O  H8 M" _  / Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits // c" y" {6 A# C* V
  #IFndef STM32F10X_CL7 N" V8 D+ B! V; P& L" X+ Q
  RCC->CFGR &= (uint32_t)0xF8FF0000;8 R# g" V; B; t( f3 Z
  #else* {( q0 A: c3 m5 B$ y) i4 l. D3 Q
  RCC->CFGR &= (uint32_t)0xF0FF0000;
) h$ K" m9 o8 _  #endif / STM32F10X_CL /
2 ~; U, b9 c5 q! U$ G  / Reset HSEON, CSSON and PLLON bits /) r* ~8 x( k. u, ~; u: O
  RCC->CR &= (uint32_t)0xFEF6FFFF;* h9 r4 c, B3 A$ C+ @4 I+ f
  / Reset HSEBYP bit // t" g/ {- w- V5 k$ s( J
  RCC->CR &= (uint32_t)0xFFFBFFFF;' m% j) \% P; N5 p
  / Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits /
0 i5 B! G% k% P/ n7 s  RCC->CFGR &= (uint32_t)0xFF80FFFF;: c* J8 o: N! h9 k8 h
  #ifdef STM32F10X_CL
9 L9 x8 f, R) Z8 M; `# Q  / Reset PLL2ON and PLL3ON bits */
8 K; E# r1 w. V5 z  RCC->CR &= (uint32_t)0xEBFFFFFF;+ l& k1 h" i: M% H, b# S# s* z- K5 \# U
  /* Disable all interrupts and clear pending bits /7 x+ ?" X' i/ c! M& T
  RCC->CIR = 0x00FF0000;
0 E9 W8 A. m3 a, J6 \  `  / Reset CFGR2 register /( F$ j1 `9 k5 d* E
  RCC->CFGR2 = 0x00000000;
1 P+ s0 O+ Q9 e9 i3 Z2 S  #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined! A9 g  h8 ]. z+ ^/ c$ K. I
  STM32F10X_HD_VL)
0 \' Q; q& f# j6 ?' F  / Disable all interrupts and clear pending bits /9 P, @0 V- ?  n0 C  w
  RCC->CIR = 0x009F0000;
  Y" y* B" y* t  / Reset CFGR2 register /4 _( n) Q, p: ^/ y9 ^, A
  RCC->CFGR2 = 0x00000000;
' {/ r; z1 D% q  l' ]3 }  #else
; y0 ~% h) _' j8 e; J; G/ y9 ]  / Disable all interrupts and clear pending bits /1 }+ y, t, s* B: g% ]  k7 m* D
  RCC->CIR = 0x009F0000;8 j. S$ e3 X; k( u0 W, R  w
  #endif / STM32F10X_CL /
+ W& C$ a; p! n  #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined
+ d2 D7 b8 l, ]# g4 N  STM32F10X_HD_VL)$ L% b% f& m2 f- L2 g; G1 r
  #ifdef DATA_IN_ExtSRAM$ R! I! M7 }7 g8 y" V
  SystemInit_ExtMEMCtl();
& f# D8 h4 K0 o4 j$ ~; M  #endif / DATA_IN_ExtSRAM /5 j2 o: r/ g" W+ @+ X
  #endif; g1 X, q: k7 l
  / Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers /; z6 I3 J/ m, o  t! R& x
  / Configure the Flash Latency cycles and enable prefetch buffer /
, Z8 Z1 i/ N. v* i* f8 I- y  SetSysClock();' U, @$ z, D. x1 }
  #ifdef VECT_TAB_SRAM7 c! P8 }6 a' u
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in Internal SRAM. /5 p* ]8 @, _: W' c
  #else5 E$ o( [( D8 L$ b# [5 @& ]: A
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in
7 g8 q1 ^; X6 `5 _) L+ S1 s  Internal FLASH. */
/ ~; M+ }$ _5 o3 S! J  #endif
# d  M& k+ W3 b5 e* ?8 K" B  }- g- H% A3 z2 Q
  SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:
& m) O7 _; \2 q4 H  static void SetSysClock(void)
# N2 H  P: s- c" n( d7 ]  {
2 D% _5 @9 \. H2 q, [" f6 `# m  #ifdef SYSCLK_FREQ_HSE# s& ?; ~, o+ w
  SetSysClockToHSE();% @! U2 o' Z; F2 {. z, L
  #elif defined SYSCLK_FREQ_24MHz
# D/ \% M6 U/ X+ @  SetSysClockTo24();
9 v/ k7 R; s- s, ~  #elif defined SYSCLK_FREQ_36MHz
; l4 Y1 j4 c, A; m# ?0 Y6 k  SetSysClockTo36();6 m/ `, i# ?: j+ l& G6 p
  #elif defined SYSCLK_FREQ_48MHz8 v0 h. T3 M3 V( G6 {* R
  SetSysClockTo48();% \4 Z2 D4 y( Z' m/ C
  #elif defined SYSCLK_FREQ_56MHz
# W/ L% g2 W  q  SetSysClockTo56();1 ]+ E$ ]) D% H0 _6 c
  #elif defined SYSCLK_FREQ_72MHz8 h0 `+ F$ f, J; ]$ V
  SetSysClockTo72();
/ a7 R7 U5 P  Y4 I- b3 c& `  #endif
, E% V8 N1 Q. H' D  }
  Q' w( w" y, _! P$ U  在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:
. Q" N, t. f7 m* T) a% o8 W  #define SYSCLK_FREQ_72MHz 72000000
2 o* ~" ]7 j. `& Y; ^# z3 j  如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:2 o( o3 w5 h! v/ D- @
  #define SYSCLK_FREQ_36MHz 36000000
2 }7 v- l+ w) z$ Z  根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:
% G- {- s/ `$ k' a  SYSCLK(系统时钟) =72MHz
0 a+ B# e) T( z5 f  AHB 总线时钟(HCLK=SYSCLK) =72MHz
/ c/ X2 q' ~3 H( N2 w8 o$ a  APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz6 G- |5 ]/ y$ D
  APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz) [# f) a* O8 \
  PLL 主时钟 =72MHz
4 {# t' T6 a3 C2 h5 d+ V9 T  在STM32中,这些时钟值是要熟悉的。( ^+ N& J; F' J2 i8 r/ k

' b8 j: w& K2 Y, T, q% p6 K9 F. a; Y7 O) g6 g( ^1 N4 N
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-19 22:07 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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