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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
  在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:) l# D- M( C% e' ?% v& a& N1 B  X7 k
  void SystemInit (void)" S5 T/ A- N. ~- z6 g) ?/ W4 y
  {
; T' h3 x7 |+ [0 V  /* Reset the RCC clock configuration to the default reset state(for debug purpose) /$ |6 l! m0 W5 K6 w
  / Set HSION bit /7 d2 K. f: Q. d/ S# a( J/ E! `2 v
  RCC->CR |= (uint32_t)0x00000001;
: p2 `- Y. _' `1 N( X6 q& j- S  / Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits /
6 l; z6 j3 Z' Z' F* _  #IFndef STM32F10X_CL
7 D2 u; g+ [! R; m4 v  A" i+ y8 X; u  RCC->CFGR &= (uint32_t)0xF8FF0000;
/ K/ \) G, \- E. |8 y  #else  O" B% s+ X# H3 c
  RCC->CFGR &= (uint32_t)0xF0FF0000;
8 `& O+ V, S6 M7 u4 [( P/ w# f7 ~# L  #endif / STM32F10X_CL /: s7 u: z0 B$ l5 ^6 I: j
  / Reset HSEON, CSSON and PLLON bits /
% ~8 Z% e' w3 ~( m# w  RCC->CR &= (uint32_t)0xFEF6FFFF;
  K* C3 u1 ]* [0 r& F0 ^4 ?" H, r' k  / Reset HSEBYP bit /& m9 u0 P9 R$ W4 c9 t0 o4 ^
  RCC->CR &= (uint32_t)0xFFFBFFFF;* J( r, q) n4 r0 _- @
  / Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits /( O- a; U/ Q- u' b; X6 m( B
  RCC->CFGR &= (uint32_t)0xFF80FFFF;
- |" `% K1 K" C: L3 |8 @0 \9 r  #ifdef STM32F10X_CL
" j/ a/ K# _+ o2 @" \  / Reset PLL2ON and PLL3ON bits */
* i- z- j( v2 @9 Z+ F# F  RCC->CR &= (uint32_t)0xEBFFFFFF;8 P- a6 h+ k. @' a2 n
  /* Disable all interrupts and clear pending bits /
0 f7 c: k+ u' b  RCC->CIR = 0x00FF0000;6 {- Y, W8 f% [0 V8 ^/ V; n
  / Reset CFGR2 register /
2 |) e% N  R9 [2 s2 k" y  RCC->CFGR2 = 0x00000000;
$ N: M9 Y9 F8 D9 K4 l  #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined
: G* B0 W1 p+ f" E; d  e4 W  STM32F10X_HD_VL)2 w! H* `8 ]1 K& t
  / Disable all interrupts and clear pending bits /
# K! C& b' M$ U0 Z: E  RCC->CIR = 0x009F0000;( `# T9 U# K; T5 m% X" d# e
  / Reset CFGR2 register /4 ~  H& C$ S' }0 R4 j' k
  RCC->CFGR2 = 0x00000000;. d4 Z  y2 F+ j3 e' p
  #else% u: U* n8 M, C2 z! N
  / Disable all interrupts and clear pending bits /$ w0 S1 y' q7 J0 o4 q
  RCC->CIR = 0x009F0000;
8 U1 p. s! C1 n1 N! U* R  #endif / STM32F10X_CL /0 a7 P/ ?4 |  U. Q9 W
  #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined4 L8 ]* L/ e% P. Y3 [4 }9 ~% r/ C
  STM32F10X_HD_VL)
. G& g, x- r+ ^$ ~2 @' M4 G' B  #ifdef DATA_IN_ExtSRAM
1 r# e5 r4 T6 D3 |) d7 V0 h7 E  SystemInit_ExtMEMCtl();
% y; g* F" J$ m, l  #endif / DATA_IN_ExtSRAM /( d1 P" ~- D# O3 k& S5 e
  #endif3 C+ Y* R* E  @# I
  / Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers /
6 S$ A. X  ?) [8 A) L) @  / Configure the Flash Latency cycles and enable prefetch buffer /
6 T- V+ r" j( V/ a+ E  SetSysClock();& U4 D& `% Q$ R/ D! I' B% N
  #ifdef VECT_TAB_SRAM
$ r) W( i8 l+ u% N6 _# d5 ^  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in Internal SRAM. /- A9 J6 q% l! b& v* @* T  w0 p7 R
  #else# z8 F* S- B, y  v& D; m
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in( j( g8 _0 g% g4 V1 M
  Internal FLASH. */
, ]6 M4 G- I! s" i# d: q  #endif1 i; ^) T& c# a( Y- A
  }
0 T7 b; C% F# }. X; _% s  SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:
5 ?2 Q! E/ _6 |  static void SetSysClock(void)' b+ N/ P. B7 z
  {
4 O  C4 ]* p& o# K9 S  #ifdef SYSCLK_FREQ_HSE
3 K. @" v; [/ m3 h( s  SetSysClockToHSE();
# N* w( s1 R9 A: t. B9 F  #elif defined SYSCLK_FREQ_24MHz
2 s/ }  C% `0 Z& w. k, ^$ n! L  SetSysClockTo24();
3 F4 u& p& V; N6 l$ Q& p% m  #elif defined SYSCLK_FREQ_36MHz
8 [9 O: V$ G5 C3 |* N9 p  SetSysClockTo36();! G! k# ^- H- @- \
  #elif defined SYSCLK_FREQ_48MHz
" ?) d$ ~' D6 p- {# G' [  SetSysClockTo48();. h/ T8 Y4 p* Y& p/ ?% j$ Y  T4 w5 O
  #elif defined SYSCLK_FREQ_56MHz  l  O' m0 O- t& N
  SetSysClockTo56();
- k8 H. M* x; {4 m4 q9 t7 T  #elif defined SYSCLK_FREQ_72MHz& D, g+ ?+ D2 {$ @; N( n" S# f  {
  SetSysClockTo72();, v( ?5 ~& p/ j, s
  #endif5 o, P/ e2 V1 k# @: T
  }& v  P0 j. Q) `, l0 [) \, o
  在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:
7 n8 T# u0 X; E5 X8 n( G8 J5 P% p  #define SYSCLK_FREQ_72MHz 72000000
* s. {: Q; A  I7 L" ?  如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:2 r% b$ q8 V8 d6 u/ s* Z0 A" \2 p
  #define SYSCLK_FREQ_36MHz 36000000
( ^& Y( i+ L* f  根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:' I& j9 s- r9 y: x
  SYSCLK(系统时钟) =72MHz* \  L5 ]$ s! C8 Z1 E2 {+ l
  AHB 总线时钟(HCLK=SYSCLK) =72MHz
" N3 b4 U  s- [& U5 Q+ V  APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz- T# u+ C" }* r8 z
  APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz
; S, I! z) A7 A, a  PLL 主时钟 =72MHz) L0 K! [5 a) W( _3 g5 G
  在STM32中,这些时钟值是要熟悉的。
3 N2 K1 b, E6 v: t& C7 {
  z3 O6 ]4 g0 @! C' w( o9 |6 X" l/ P* Z$ O) K
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-21 12:57 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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