14.1 初学者重要提示
9 N1 A0 `' d d: \1 B1、 电源管理部分涉及到的各种低功耗方式会在后面章节中为大家讲解,当前阶段仅需了解低功耗属于电源管理部分即可。
" Q6 W, O, u2 v( \# Z d6 b2 a Z
9 X @ d5 b- ?( f' P- s9 J2、 电源管理部分最繁琐的就是CPU,D1,D2,D3域的各种运行,待机,停机状态切换,这部分知识点也放在后面低功耗章节学习。
# C( v1 y: p' N# d) j
( H' M/ A7 G; w$ f, u14.2 电源( g+ A( J2 H. |" ?% V) s7 W4 G
电源是系统稳定运行的根本,主要分为以下几个知识点,电源供电、供电监控、电源管理和低功耗。当前阶段主要了解电源供电和硬件上电时序。1 r$ D. [9 _' V$ ^- B2 ]# G! n( R
. }( C; p D- n/ `14.2.1 电源供电
/ }0 f+ ?; @& @, V3 B" C4 C学习STM32H7的电源供电,往往被一堆电源标识Vdd,Vdda,Vcap,Vss等搞迷糊,这些标识整明白了,电源供电部分也就理解了,首先看下面的框图:6 z/ j; V. A. Z4 x- E. ~
) s j9 w) c6 l* c/ E' s& W
! I4 V& G: E6 I
0 T* b( c' x$ P0 C" W* F' s N7 v这些常用标识的解释如下:2 L3 Z) I* d/ q% X4 k8 c* s
" u' g" V# G( ?/ [6 s
" V& N* |" V0 D; R
! h+ F5 I& P+ k对于电源供电部分了解了这些知识点就够用。. l- |$ p& F& i6 {9 T4 O0 G
# ]5 m2 ~) X8 J Z7 y0 ^3 G. N% T
14.2.2 系统上电启动
. h) \# W' T# T1 a% J+ f' k% r系统上电到程序开始运行期间,H7都做哪些工作,一张时序图可以说明问题:& r; k$ _! }& r5 h5 m
, x3 b( `1 \4 n9 ~; W" C2 T4 Z( Y, F
3 K4 b9 Z6 E5 F0 d: q2 D
对于上面的截图,主要看Operating mode部分,依次是Power down –> Reset -> Wait Oscillator ->HW system init -> Run -> Wait ACTVOS RDY –> Run,即断电状态 -> 复位状态 -> 等待HSI就绪->硬件初始化 -> 运行 -> 等ACTVOS位就绪 -> 正式运行。6 w* a, z+ f& q" ~8 ~2 F' V
* m: A' H3 T0 G* r& J3 M详细些的执行流程如下:
4 ]! c) T# d& Y1 z [$ P2 @. f
+ F" |4 J9 P* N+ E z) j6 {; [ 当系统上电后,POR(Power on reset 上电复位)会检测VDD供电,当VDD大于POR设置的阀值时,将使能电压稳压器,注意看VDD那条线的变化。
. w( l8 ?$ Z, O5 m4 o4 ~, R 看VCORE那条曲线,只要VOSRDY未就绪,就会一直处于复位状态。 x4 |( f, t, @ v
一旦VCORE正常输出,系统将走出复位状态,内部高速RC振荡器HSI将使能。
! C1 s; ?" V% U# a( N0 M: B$ f HSI稳定后,将开始系统初始化,主要是Flash和可选字节的加载,这些都是由硬件完成的,CPU也将以受限的方式运行(主要是指不允许对RAM进行写操作)。: ^) ^: n/ F% |) d7 |* Z
软件程序初始化系统,包括供电配置。当供电配置完成后,等待ACTVOSRDY位置1,完成置1后,CPU就进入正常的运行的模式,允许读写RAM了。
6 ]# E% H( y {& k* W4 n14.2.3 电源管理
- u* u b0 i! Q* x5 g4 {$ p关于电源管理部分,H7参考手册中讲解的还挺复杂的,当前阶段我们仅需了解几个重要的工作状态即可,看到这几个单词了要认识,因为官方文档中多处要用这几个标识。) C* @ i- u& ?$ ?; \. Y5 _! c1 R
( I4 d% ?( H' h( l
为了实现各种低功耗模式,CPU和D1,D2,D3域支持的各种模式如下:4 u2 `& p' ?& j
3 {: M I, N4 L0 n+ J, } CPU模式( S; n! \# r% J I1 ]( T0 T
CRun:运行状态,CPU和CPU子系统外设正常运行。7 W( a; x' j A3 A6 ]
) n( k1 m3 N. o$ g
CSleep:休眠状态,CPU时钟停止运行,CPU子系统外设正常运行。
- ]# `) n! q+ T1 \+ H4 }- [6 C% }; t
CStop:停止状态,CPU和CPU子系统外设都停止运行。
1 @, f6 R" Z. L1 m5 Q
9 f; y8 z- a0 G( F' Z# B8 \: R D1域模式# h# V- @$ G2 V4 L$ K, r% x! d
DRun:运行状态,D1域的总线矩阵正常运行,CPU子系统运行在CRun或者CSleep模式。
; U- X- O0 s' m1 [; Y+ K! k8 c4 I: r J0 B- u! b \9 \2 R
DStop:停机状态,D1域的总线矩阵时钟停止运行,CPU子系统运行在CStop模式,PDDS_D1位选择DStop模式。
8 m$ e Y! ]% r% v( T8 a9 m7 f1 R: Y7 m/ D# e
DStandby:待机状态,D1域的总线矩阵断电,CPU子系统运行在CStop模式,PDDS_D1位选择DStandby模式。5 x% _# S" C, A! U/ G
/ F S3 O+ G8 }' K D2域模式+ k: W2 O+ v: U$ D4 L/ G
DRun:运行状态,D2域的总线矩阵正常运行,CPU子系统在D2域中有分配的外设,CPU子系统运行在CRun或者CSleep模式。+ m" S: }1 v) v( n) H/ A5 q
& Z! @8 A7 i o/ W' v4 ~DStop:停机状态,D2域的总线矩阵时钟停止运行,CPU子系统没有在D2域分配外设,PDDS_D1位选择DStop模式。或者CPU子系统在D2域中有分配的外设,CPU子系统运行在CStop模式,PDDS_D1位选择DStop模式。9 ]$ z- f- E" m+ {
) n$ _; b6 M5 a1 R2 I% CDStandby:待机状态,D2域的总线矩阵断电,CPU子系统没有在D2域分配外设,PDDS_D1位选择DStandby模式。或者CPU子系统在D2域中有分配的外设,CPU子系统运行在CStop模式,PDDS_D1位选择DStandby模式。3 {. ^( Z- |6 H
5 G4 b; h% n* J3 L 系统/D3域模式$ `# z( V+ e7 Z9 [( C7 m; n5 ~: V; ~
Run:运行状态,系统时钟和D3域总线矩阵时钟处于运行状态。CPU子系统处于CRun和CSleep模式,或者一个唤醒信号处于激活状态。
5 m( ~0 m8 S9 K- ?! E1 j$ m
" J$ }% a- n$ |8 Q! UStop:停止状态,系统时钟和D3域总线矩阵时钟处于停止状态,CPU子系统处于CStop模式。所有的唤醒信号都处于非激活状态,并且至少某个域的一个PDDS_Dn位选择了Stop模式。
; q1 J7 H3 D1 V* C9 c. g0 y* U, t
* |) c) ^& h. w3 m( R+ rStandby:待机状态,系统处于断电状态,CPU子系统处于CStop模式,所有的唤醒信号都处于非激活状态,并且所有域的所有PDDS_Dn位选择Standby模式。
4 F& Q0 k m; |3 {/ a
^5 j$ B$ I' I7 j9 O14.2.4 电源去耦电容的选择
2 j: t# @2 [5 e" y( I4 i1 ^每个电源对 (VDD/VSS, VDDA/VSSA ...)必须使用下述的滤波陶瓷电容去耦。这些电容必须尽量靠近芯片引脚,以确保器件正常工作。不建议去掉滤波电容来降低PCB 尺寸或成本,这可能导致器件工作不正常。 & N" f' ?% t% s- z* k
5 ~$ s' z8 d, B d' W
& d) U# f0 `' b* x
$ {& `2 A9 d2 r$ a6 D' N( n
14.3 硬件复位6 e3 }, }- b; h
所有数字计算机系统都是由某种形式的震荡时钟电路驱动的。这种电路被称为系统的“脉搏”,是系统正确运行的关键。如果振荡器失灵,系统将完全无法运行,如果振荡器运行不规律,系统执行的所有与时间有关的计算都会有误差。/ C( x! C2 `3 V" ~# v
+ W1 I0 I: K' p! A9 B所有微控制器的启动流程都不通用。由于硬件的复杂性,必须运行一段由厂家定义的短小的“复位程序”来使硬件处于一种正确的状态,然后再开始执行用户程序。运行这个复位程序需要时间并且要求微控制器的振荡器已经运行。
1 `1 O/ z" T9 Y! d* f% ]( w9 t" q0 M0 {1 ^4 `
当系统由可靠的电源供电时,一旦通电,电源迅速地达到额定输出电压,一旦断电,电源迅速地下降到0V,并且在接通的时候,电压不会降低。这时能够可靠地使用基于一个电容和一个电阻的低成本硬件复位。这种形式的复位电路称为阻容复位。9 i' c8 ^2 n$ V" d5 w
" ~3 y* Z& `/ o, N( ?如果电源不够可靠,而涉及安全性,这种简单的阻容解决方案就不合适了。
/ D" A$ Z+ ^" ]8 j$ }1 N
' Q6 q+ O, z' M# K% p: x* C14.3.1 上电复位和手动复位: m2 Y9 {2 o0 M( R/ ^
STM32H7开发板的硬件复位原理图如下:4 M6 E( H6 y- O
7 j) ]( k- M, W: K* F/ C u4 f5 x
& n: |" i! h: P! p
: O8 ^& S) C$ l3 O0 s6 L& R( N: _
STM32这款CPU的复位引脚是低电平有效,即NRST为低电平时,CPU处于复位状态。
4 g5 G% I1 q, l7 y R173单的RC复位电路。当系统上电瞬间,C114电容两端电压可以认为是0,CPU处于复位状态。3.3V电源通过R173给C114充电,当C114的电压升到CPU的高电平门槛电压时,CPU退出复位状态转入运行状态。! d4 Z0 P" q& c+ P
在设计电路时,需要选择适当的R值和C值,以保证NRST低电平持续时间满足CPU复位最小脉宽的要求。
) X, X6 a# B9 A/ T( R6 j1 { 当按下S4轻触开关时,C114两端被短路接地,可实现手动复位CPU。
5 P2 v ]5 I8 n/ W$ z9 e
" [4 x% |: J* U5 J* y7 S- n& G14.3.2 复位序列
/ G- {/ k% S) K3 s$ \7 O前面第11章的13.3.1小节讲解了复位系列的相关知识,再结合本章节的上电复位和下电复位,大家会对其有一个较全面的认识,更多复位序列的知识直接看13.3.1小节即可。
& C4 L7 ?+ S9 N% ?+ |, V& y% |4 @! Y. v4 r
14.4 软件复位* x$ E" E% e- t/ L
除了上电和手动复位,程序设计设置中还经常要用到软件复位,即调用一条函数就可以实现复位功能。此函数已经由CMSIS软件包中的core_cm7.h文件提供,函数如下:' Q8 y) @% s+ N4 L+ a, b
7 I0 m g+ \% g6 t) |# U- /**
; `- T: z* n. r - \brief System Reset' O' J* E% e$ O' I
- \details Initiates a system reset request to reset the MCU.! d0 x' m1 h! W! j
- */
* r$ k6 I f+ i! ~- M1 G6 m6 J, y - __STATIC_INLINE void __NVIC_SystemReset(void)
0 [# c1 Q6 h7 H. d/ F1 @3 p - {
" R( W$ l# W1 P4 d! v - __DSB(); /* Ensure all outstanding memory accesses included# \2 s/ D; Q6 l. W! R$ _$ H
- buffered write are completed before reset */2 o& G; m0 ?8 k
- SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |4 D( e% p7 K4 [
- (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |, Z0 p7 x) _" o! P5 t
- SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */% K" i5 B& U3 M
- __DSB(); /* Ensure completion of memory access */
3 g7 k. r( I. ~# R+ f8 i3 M - / {7 [, l4 j( ?) [
- for(;;) /* wait until reset */8 A6 U5 ~4 }7 Y8 j- N# n4 b3 s
- {
; k" e5 a7 [0 ^) g$ a9 j7 _* m3 R% j - __NOP();
$ d. q$ M' l0 ?7 i# c - }) ^/ h) y: U. @/ j7 T5 q# p
- }
复制代码
) l {3 U; \& w& f. z软件复位反映到实际硬件上,就是给硬件复位部分发一个复位信号:
0 c: m- O: G# K! M1 U5 X0 m
- Q0 ]. i' w( m. V8 h$ Z$ Z2 s0 k$ g0 i3 i( X, d
6 q' g" S) Q/ W14.5 RCC时钟控制3 m$ I. D8 N6 ]5 a# g; J5 v% ?$ l1 D' g7 l
STM32H7有如下六种时钟可供使用:) z% H I$ x' t' o
3 R- r4 {' d& Q. m9 j) @1 f2 h HSI (High-speed internal oscillator) :
3 X8 m3 P. |5 s3 G5 l2 j% D0 dHSI是内部的高速RC振荡器,频率64MHz,可被用于系统时钟。优势是低成本,无需外部时钟,快速启动(仅需几个微秒),缺点是精度差,即使经过校准。
" A0 |8 g/ c6 X' t8 I* t. f/ [' n
HSE (High-speed external oscillator):9 ]' S+ p9 \$ R3 e- e
HSE是外部的高速振荡器,通过外接时钟源,有源或者无源晶振驱动,时钟范围4-48MHz。优势是精度高,缺点是增加成本。
! X" v$ c: i! h# J$ z
: X9 ?3 Y0 w. _8 Q3 o LSE (Low-speed external oscillator)/ Y! R) }& C- c' C4 W; Y A+ B7 b9 B
LSE是外部的低速振荡器,通过外接时钟源,有源或者无源晶振驱动,一般接32.768KHz,主要用于RTC实时时钟。
6 u2 L+ r/ g6 n# h: `* K9 V; C5 Q% l, }
LSI (Low-speed internal oscillator)* G2 e5 I4 d2 B3 q4 ~3 z0 W5 N
LSI是内部的低速RC振荡器,频率约是32KHz,主要用于独立看门狗和自动唤醒,也可以用于RTC实时时钟。
0 ^2 Y' [4 A$ N) f$ }& `; ?
& \5 L- G) O) `1 e: `: X' f( R: a& U/ a CSI (Low-power internal oscillator)$ t: G# y' I' }! d8 N6 J
CSI是内部的低速振荡器,频率约是4MHz,相比64MHz的HSI,主要用于低功耗。: b' ~' G7 g- _7 w6 Z6 H
; t$ U( a6 y4 ?5 y HSI48 (High-speed 48 MHz internal oscillator)/ J2 M0 I. ^# ]# W; i
HSI48是内部高速振荡器,频率约是48MHz,用于给特定的外设提供时钟,比如USB。/ T u! `& h+ T$ @" O6 J) G
4 I' l; ]8 k# X通过下面的时钟树再进一步的认识这几个时钟:4 P1 Z$ N7 i# p& y+ t
9 x" P4 l4 k; d& J& `/ M! t3 l& I6 q* f
* [/ \8 ?, K6 k2 u, x$ r14.5.1 HSE和LSE硬件设计
% r* K! B. i0 a4 o- F- b+ { HSE时钟! W, J. s3 a* d! d3 o% t
当前V7开发板是用的25MHz晶振为HSE提供时钟,硬件设计如下:# B! w: v/ f4 s Y
8 |* p- C" E- S, f. F4 x% z/ T/ P3 q; b$ v" E
7 b3 X6 G8 z7 N, l2 f+ G
晶振和负载电容需要尽可能近地靠近H7的晶振引脚,以减小输出失真和启动稳定时间。负载电容值必须根据选定的晶振进行调节。- o6 y: u6 Z. T7 I, s, Z: b
* s5 G% _. i6 N5 m) E对于C15和C17,我们推荐使用高质量陶瓷电容,这种电容是设计用于需要高频率的场合,并且可以满足晶体或谐振器的需求。C15和C17通常具有相同的值。
# s1 S7 k( T3 R& r& j) t& P! M! K t: C5 [
这里再额外补充一个知识点,HSE旁路时钟和外置晶振区别:当前V7板子是采用的外置晶振模式,高速外部 (HSE) 时钟可以使用一个4到48MHz 的晶振 / 陶瓷谐振振荡器产生:
8 I7 w) T' ~% b$ @3 a3 p: D4 k% S; J, ?) S3 X# Y8 ]$ T- A
N" d. ~# e, l: {$ L g& N# ]- s
而bypass 旁路的意思就是不使用它,绕过它。具体到HSE旁路的话,用户直接提供4-50MHz的时钟源即可,可以使用有源晶振或者FPGA提供时钟等方式:% ?+ I- o6 |9 b% o0 C
( S% Q( \8 {' i# l, h6 ?' `! r, e! O# o' ~* `. t) I
" I# W% E9 d* x( _0 m1 Y& j LSE时钟5 H$ @+ i" `% f4 G0 s. c
当前V7开发板是用的32768Hz晶振为LSE提供时钟,硬件设计如下:
# p1 T4 g6 k' j0 e3 N
* ?/ Q+ U+ x; x* I. h$ t7 }5 [0 S+ L) w5 u
1 Z$ a: m, @: y( m. {% E+ n7 {0 v, y) u" {
14.5.2 时钟配置' J S5 v2 ]2 d- R. c; A
STM32H7开发板使用的外部晶振频率是25MHz,下面分步说明如何让其通过这个频率工作到400MHz的主频。
* h- M, Q1 a- U2 I* h
! L, ^: a9 P% y5 K# w4 i# Y 第1步:在stm32h7xx_hal_conf.h文件配置HSE_VALUE1 w E8 U; Y c0 K
配置的大小要跟板子的实际晶振大小匹配。0 c( X& _5 n. l- I
8 F2 q' S6 W- f- J% P- #if !defined (HSE_VALUE)
7 @8 O- T M' C - #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ : T/ g n2 ~6 L* ]8 y; K9 M" \
- #endif /* HSE_VALUE */
复制代码
9 n) ]5 s, |7 @ 第2步:系统上电后,在启动文件startup_stm32h743xx.s的复位中断服务程序里面会调用函数SystemInit。
: w) b% S5 X1 k# H3 t7 Q- Reset_Handler PROC
! K9 P) U. I7 m - EXPORT Reset_Handler [WEAK], Z" l! D4 ]# V& H; w( h; Z
- IMPORT SystemInit
* R+ m! b. E% a: t3 I" |- y( ` - IMPORT __main
; M( P0 j! O) N/ `; ~( n- n - ! Z# K, F+ z/ s2 E1 E
- LDR R0, =SystemInit, n, B4 Y9 X4 K6 c
- BLX R08 G4 \7 ]% i3 Q) a5 Z, L' d
- LDR R0, =__main
& g, S/ f6 W( E4 Z1 d - BX R0; o/ Y2 E* x4 Q2 b7 A
- ENDP
复制代码
; @8 d4 c* G4 ^1 O. r* O' [& s& y以往STM32F1和STM32F4系列都会在函数SystemInit里面配置PLL锁相环,使用了HAL后,需要在main函数里面配置。当前SystemInit函数实现的功能如下:
& Q/ K1 w+ P+ `
8 {6 X- }) ?6 t6 X- 1. /**
s7 E' ^1 G& @2 [% w2 ^! A& X& L - 2. * @brief Setup the microcontroller system
7 S/ e, j! u. Z - 3. * Initialize the FPU setting, vector table location and External memory
: P- X! ~8 G2 Z8 N - 4. * configuration.2 U3 n! j4 z. K/ V( ? h( p4 Q9 f
- 5. * @param None0 }! U8 U {! F# T$ s! D. p0 N) l
- 6. * @retval None
. x$ K: E+ F S9 X" r3 B* n1 T - 7. */! c$ v: `# ~. U8 a& {6 L
- 8. void SystemInit (void)
& U" v4 M! g4 [3 {9 v7 _ - 9. {
: ], P- x0 c6 ? D0 \& ^8 `$ a7 D5 T - 10. /* FPU settings ------------------------------------------------------------*/
) Q, B5 i0 i8 S, i2 s - 11. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)) I; b, M3 t; D. \
- 12. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */6 g* g% N# H, K: s9 U f% C
- 13. #endif
3 B9 E! ]$ v# W* h3 I% U" d7 s' t. u - 14. /* Reset the RCC clock configuration to the default reset state ------------*/
: E Y C$ b9 e$ { - 15. /* Set HSION bit */' _8 p5 ?4 L3 W& B7 u
- 16. RCC->CR |= RCC_CR_HSION;8 d. L! J! |5 p2 X. C9 m
- 17. . L8 R, l5 L+ Z
- 18. /* Reset CFGR register */
v) \0 e5 B6 T m1 O4 c( R - 19. RCC->CFGR = 0x00000000;/ }9 u6 ]2 D" e+ I- C
- 20.
6 @8 k% }- G7 c# P$ l - 21. /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
/ `7 f. T+ O* |3 q- V - 22. RCC->CR &= (uint32_t)0xEAF6ED7F;
/ U, P! X5 |% L4 Y* d4 A- ?, B# V - 23.
9 u; H1 H3 ^& |. ?4 J4 D - 24. /* Reset D1CFGR register */$ H4 r. J2 B$ N$ K
- 25. RCC->D1CFGR = 0x00000000;+ \6 o4 Q! g" |: w; m7 f) M! U3 D, j0 J6 ^
- 26.
% N- X/ c2 J# @2 i% e$ m2 I* q - 27. /* Reset D2CFGR register */
1 Q6 m; ?) k! E: v# N. Z( U0 t - 28. RCC->D2CFGR = 0x00000000;! V; l1 O- m. _- |% a# E: H
- 29.
# X( r, w4 `6 ~( ~ - 30. /* Reset D3CFGR register */0 Z1 _* o o+ x
- 31. RCC->D3CFGR = 0x00000000;
! a" t5 v: p- ~! i - 32.
% H4 a7 D; o, U! C& I - 33. /* Reset PLLCKSELR register */' m x" {8 [6 P
- 34. RCC->PLLCKSELR = 0x00000000;7 R3 O% x/ x: ?' }
- 35.
( @/ F( g, a, D( b- ?& p9 X8 v - 36. /* Reset PLLCFGR register */
# [2 Q' Y" W/ [+ l - 37. RCC->PLLCFGR = 0x00000000;
: u* h" E' ]0 l7 I6 \# | - 38. /* Reset PLL1DIVR register */3 }4 U" R2 ?) ]( Z6 i
- 39. RCC->PLL1DIVR = 0x00000000;
/ L) W0 F' T: O. m& _ C - 40. /* Reset PLL1FRACR register */
- M6 s4 h) {, r - 41. RCC->PLL1FRACR = 0x00000000;
: @$ a0 c. l+ ? - 42. $ l. i7 ~( @2 t3 E7 U
- 43. /* Reset PLL2DIVR register */
' v0 Z1 D8 L" N7 ]5 h3 a. v! A - 44. RCC->PLL2DIVR = 0x00000000;
" d ]/ K" c- Q( \: y - 45.
7 u" I$ y) h/ P3 C4 h - 46. /* Reset PLL2FRACR register */ N4 R9 ?7 g; @8 T& h& }, j, Z4 V
- 47.
6 _8 {# Q8 S4 [* L' K( C5 q4 M - 48. RCC->PLL2FRACR = 0x00000000;
" w( q ` I! I+ C, q - 49. /* Reset PLL3DIVR register */1 s( z8 U. a4 Y4 j
- 50. RCC->PLL3DIVR = 0x00000000;
6 v# @' i0 |- f; e; C9 k - 51. 9 N3 Q: `0 A% ^& _* ? s
- 52. /* Reset PLL3FRACR register */
/ a0 ~ x, [! i. \$ _- S/ F0 } - 53. RCC->PLL3FRACR = 0x00000000;
1 O a! }5 Q+ F - 54. * T) T) i5 m) ?. s. V! l
- 55. /* Reset HSEBYP bit */* D6 H( V/ _. h: t
- 56. RCC->CR &= (uint32_t)0xFFFBFFFF;
~) @ b3 z' n5 Z9 C+ ?! f - 57. 2 |' P8 z# X% @+ P" S
- 58. /* Disable all interrupts */
9 C* j, R* {6 Z$ L! C - 59. RCC->CIER = 0x00000000;! U- T+ [* u w# w0 a! Y5 c
- 60. $ v( \; ^! i# g* O7 y! Q" i: H! M
- 61. /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
[: E+ Q, A$ A* G! i - 62. *((__IO uint32_t*)0x51008108) = 0x00000001;0 [+ i! l! x; b1 C* s
- 63. * {, l. O) y" g* x5 o
- 64. #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)* \9 |& W2 m& `
- 65. SystemInit_ExtMemCtl();% F& D# k* R" k
- 66. #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/ K6 |0 B, f D* n# v - 67. : [9 C1 K% D, o5 |- D% |" s6 e
- 68. /* Configure the Vector Table location add offset address ------------------*/
+ ]9 b9 p5 r' V( h3 \ ~ - 69. #ifdef VECT_TAB_SRAM
9 K" m! ^, c6 s/ r, i - 70. SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal ITCMSRAM */
+ f( k# o. q6 w- P/ f/ z& O! i - 71. #else
. S9 m% Y. `7 y4 p - 72. SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */. {8 K! ^, s) q2 d; y! B
- 73. #endif. }5 n; [4 A9 y
- 74.
- Y' P3 O. c4 c$ I' G - 75. }
复制代码
& y" G& ~/ i$ W' v: `- \第12行:使能FPU单元。: ]# a/ [$ S( [: S- `# F5 \
& j6 R/ s+ M. L% d* }4 G( Q第16 – 59行:复位RCC相关寄存器。
( j9 c f' L8 x+ k4 D- s( u) n# q& m
第69 – 73行:设置中断向量表的位置。
- n4 p* l5 a4 g/ k; L1 Y% G# h" W1 C# L
第3步:在main函数的外设驱动初始化函数里面完成时钟初始化,主要是PLL锁相环,让芯片最终工作到400MHz。
) a/ w! s! o* u" i4 j; E14.6 总结, y7 z1 U% P, U
本章节就为大家讲解这么多,本章节的知识点相对比较多,比较杂,不容易一下子都掌握了。随着后面章节的进行,还会深入的讲解这些知识点。
1 c8 \, F8 L2 J/ p3 w
/ S+ L% x- A3 L5 W, r9 b) x2 h7 T+ ?
$ n' V) {8 h5 e. T& f, G
|