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

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

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

void SystemInit (void)
2 z- t5 ]$ I4 T( M/ G{
) L: l, s( A% X  h, X6 Y/* Reset the RCC clock configuration to the default reset state(for debug purpose) */2 P* ^; F! l" x8 a' r( Q
/* Set HSION bit */
, u1 y6 z/ _" R7 {RCC->CR |= (uint32_t)0x00000001;% L& n- e) q8 @  v- R# F$ f
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */5 N5 o( o' V! a2 m
#ifndef STM32F10X_CL
5 }! x, I5 m9 C* z# N* mRCC->CFGR &= (uint32_t)0xF8FF0000;
- z8 E3 m) J- r6 _* `' O# K. a#else
8 ~9 R; c" O  X% ERCC->CFGR &= (uint32_t)0xF0FF0000;
5 g0 R. |- O* c& f6 H8 Z4 |8 ^  }#endif /* STM32F10X_CL */
" t$ Z! l) k% u& N" ?* r5 @0 B/* Reset HSEON, CSSON and PLLON bits */$ R, z2 b. P1 d9 y. j- P
RCC->CR &= (uint32_t)0xFEF6FFFF;
, E7 }" v0 f* _7 i/ T& H0 m8 g* Q/* Reset HSEBYP bit */$ t0 T6 A. E* X% Y2 f$ Y4 U% `
RCC->CR &= (uint32_t)0xFFFBFFFF;/ ]1 [& t7 P' F  ^! [1 _0 i
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
- g) o: A% `# ~1 U4 A' t. pRCC->CFGR &= (uint32_t)0xFF80FFFF;
- B1 f& {0 `0 v7 c2 e/ V#ifdef STM32F10X_CL9 y7 Q8 v7 J' b! H$ d
/* Reset PLL2ON and PLL3ON bits */
$ q7 U( z5 ]! ~RCC->CR &= (uint32_t)0xEBFFFFFF;
7 y# Q! L" \( c' `
/* Disable all interrupts and clear pending bits */
+ r* M- f" k! C" G2 o1 ERCC->CIR = 0x00FF0000;6 u; ^# Y0 \; d; z0 b
/* Reset CFGR2 register */4 S4 t6 \9 M% i8 B
RCC->CFGR2 = 0x00000000;; f( a' }  A& X& g
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined
4 i* E. }; {9 QSTM32F10X_HD_VL)
8 P0 y  N1 O# B' _0 ]/* Disable all interrupts and clear pending bits */% x6 @- ?1 A+ F; Y) n! Q9 ~& v
RCC->CIR = 0x009F0000;
2 W7 |3 C! {% i& p6 W. n/* Reset CFGR2 register */
7 j3 w& _6 b7 M! HRCC->CFGR2 = 0x00000000;
: F& _; E# m+ Y8 b1 f6 r#else
; V0 U  ]$ o8 B# X2 M/* Disable all interrupts and clear pending bits */
. c- \& H3 o" G/ P$ v8 m) wRCC->CIR = 0x009F0000;
, @* L+ R8 B/ u( R$ ?$ u7 T; x# K4 H#endif /* STM32F10X_CL */2 y# w# S( A4 B
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined9 y1 T6 d9 X! C* q
STM32F10X_HD_VL)
$ i% c1 P1 y3 T; X! _% {$ w8 R" C9 F#ifdef DATA_IN_ExtSRAM0 W) w" W0 J4 g$ F$ v; Y3 Y, ^
SystemInit_ExtMemCtl();5 W% O8 K# u; ~& l, }* n2 W
#endif /* DATA_IN_ExtSRAM */: O! @; K: T& O. O& {* E" c9 M6 |  o
#endif- l! y" w* t) D! s
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */0 D* ~3 c3 }1 [
/* Configure the Flash Latency cycles and enable prefetch buffer */' ]4 _) r4 l7 T0 I
SetSysClock();) \! l8 b. J' n& M: M. V: K# N# ?; F, Y
#ifdef VECT_TAB_SRAM
  J. v# k4 G3 ]* b- y0 ?2 {) T6 M' TSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
- j3 s/ a0 i1 f7 b$ H#else, U  s' u3 V. R% n
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in
- k% V9 P2 b  k8 JInternal FLASH. */
6 R4 f& i  d* L8 |. {#endif
6 q/ M. o7 A6 Y; G5 a}

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

static void SetSysClock(void)
, ?+ c0 j% ~# @{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz) n, G0 ~+ M# \; {2 \  H" a' D: ?" v
SetSysClockTo36();
- y. m' C/ K$ Q) m. W, M#elif defined SYSCLK_FREQ_48MHz
- T7 v7 v  {1 @$ B9 u4 rSetSysClockTo48();
2 B: S# T- |) f2 |' o; f$ ^#elif defined SYSCLK_FREQ_56MHz$ p2 ?+ g- l  X. m3 E5 D
SetSysClockTo56();
0 p' x7 Y4 L  d1 G# |#elif defined SYSCLK_FREQ_72MHz2 F- |: E# x, x! m
SetSysClockTo72();; d" \+ [+ J$ ]$ ?) a4 O& ^
#endif
}

  在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:' Z! R: N6 H( ~( C3 j

#define SYSCLK_FREQ_72MHz 72000000
- F, z# D! ^6 L2 X

  如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:& Q7 b6 e% x, e- G! H, k, Q, K7 Y  |

#define SYSCLK_FREQ_36MHz 36000000
8 |+ G$ K( i' b: D% Q$ h

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

SYSCLK(系统时钟) =72MHz
* \6 A: J$ x- O) S) a! k9 O/ gAHB 总线时钟(HCLK=SYSCLK) =72MHz. s  M1 x3 }; K( Y9 ], C
APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz+ {0 x; u8 ?: q& q- a
APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz
' c) W; t8 k3 Y- @PLL 主时钟 =72MHz
9 p( i4 ]( v7 f: t; k$ `( ~. }0 c

       在STM32中,这些时钟值是要熟悉的。
6 ?, d; k" {  ?: P
赞 收藏 评论0 发布时间:2022-7-1 13:11

举报

0个回答

所属标签

相似技术帖

官网相关资源

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