|
STM32复位来源,以及系统和内核复位区别
' V% {8 E( S9 U8 L# Y, }最近有朋友问了些关于STM32复位的问题,今天结合前面文章再次总结一下复位相关知识。 1 STM32的复位和时钟控制 RCC:Reset and ClockControl 每一块STM32中都有这么一个RCC复位和时钟控制模块。 STM32的复位为三类:系统复位、电源复位和后备域复位。 系统复位: 1. NRST引脚上的低电平(外部复位) 2. 窗口看门狗计数终止(WWDG复位) 3. 独立看门狗计数终止(IWDG复位) 4. 软件复位(SW复位) 5. 低功耗管理复位 电源复位: 1. 上电/掉电复位(POR/PDR复位) 2. 从待机模式中返回 备份区域复位: 1. 软件复位,备份区域复位可由设置备份域控制寄存器(RCC_BDCR)中的BDRST位产生。 2. 在VDD和VBAT两者掉电的前提下, VDD或VBAT上电将引发备份区域复位。 2 STM32的复位来源 在很多应用中,都会判断是什么引起的复位。 比如:判断为看门狗引起的复位,我们进行xxx操作。软件引起的复位,我们又执行xxx操作。 在STM32RCC模块中,有这么一个寄存器:控制/状态寄存器 (RCC_CSR): 这个寄存器就会记录各种复位的状态,我们直接读取这个寄存器(库函数有读寄存器接口)就能知道是什么引起的复位。 3 STM32的复位来源例程 之前我提供了一个简单 Demo , STM32F103ZE ( Keil ) _ 复 位来源(寄存器版):
2 G& T' J/ y+ _* ?
4 STM32系统和内核复位 内核复位:它会使STM32内核(Cortex-M)进行复位,而不会影响其外设,如GPIO、TIM、USART、SPI等这些寄存器的复位。 系统复位:这个复位会使整个芯片的所有电路都进行复位,系统默认的函数接口NVIC_SystemReset就是系统复位(位于core_cm*.h)。 1.NVIC_CoreReset内核复位 CM3 允许由软件触发复位序列,用于特殊的调试或维护目的。在CM3中,有两种方法可以执行自我复位。第一种方法,是通过置位 NVIC 中应用程序中断与复位控制寄存器(AIRCR)的VECTRESET 位(位偏移:0)。 这种复位的作用范围覆盖了整个CM3处理器中,除了调试逻辑之外的所有角落,但是它不会影响到 CM3 处理器外部的任何电路,所以单片机上的各片上外设和其它电路都不受影响。 C语言版函数: - <p class="MsoNormal"><span lang="EN-US"><font color="#000000">void NVIC_CoreReset(void)<o:p></o:p></font></span></p>% {" e: D6 _0 O: N& o5 X( C4 p
}3 h% L+ N! N# t" _1 I7 c1 w3 l; R- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">{<o:p></o:p></font></span></p>
# M: Z$ m5 c7 S/ Q1 y+ g - 6 U* H2 {* ^" v8 A; C* p+ p. j) D$ I
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> __DSB();<o:p></o:p></font></span></p>/ ?$ q* w4 k9 g5 g0 r
- - ]9 o' f: n# J2 f) ]' i% J
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> <o:p></o:p></font></span></p>1 |; E9 m. f* Z% s
0 a; j* }: F+ t0 m |. u3 ^0 U- <p class="MsoNormal"><font color="#000000"><span lang="EN-US"> //</span>置位<span lang="EN-US">VECTRESET<o:p></o:p></span></font></p>
; e7 F( k! g# F6 q P - # E7 E: }" V( E$ \) Q4 f7 a
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> SCB->AIRCR
' e$ p" `) V+ x4 B6 [9 @, y - = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |<o:p></o:p></font></span></p>
) X$ H7 O, K/ Z0 j0 \6 F - * h& o: U0 I/ H! ^# r$ n
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> (SCB->AIRCR &! |; g2 s$ J4 H: h$ _" g
- SCB_AIRCR_PRIGROUP_Msk) |<o:p></o:p></font></span></p>
# D. [5 p* B8 {
' c0 [5 Y' a! ?- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> SCB_AIRCR_VECTRESET_Msk);<o:p></o:p></font></span></p>
( D$ e8 x' T, S1 `+ z4 M- d7 W `- ~! G
. o5 b: O( O, k& z6 R$ Z6 d- W- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> __DSB();<o:p></o:p></font></span></p>; w2 J8 Q9 x0 @
- ! E0 t2 U- @; h& i6 B
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> while(1);<o:p></o:p></font></span></p>
( e3 S5 _( e! }( `8 I% p - ) Y* B( W1 S/ p# d* D I! o5 }
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">}</font></span></p>
复制代码 2 J1 A- N3 b( P9 o
汇编版函数: - <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">__asm void% ^4 n( s# P J9 \$ C
- NVIC_CoreReset_a(void)<o:p></o:p></font></span></p>$ }. A* Z, f3 H2 G& T5 B
2 x! N2 ?3 G0 Y0 q9 c% E6 Q- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">{<o:p></o:p></font></span></p>9 `9 V4 X" X: B6 k( q2 E
- % Q+ ^0 v4 I3 h0 L- J% h U
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> LDR R0, =0xE000ED0C<o:p></o:p></font></span></p>% ? r9 ~7 ?9 g! I& ~
- + N. f9 \ G7 V$ G
- <p class="MsoNormal"><font color="#000000"><span lang="EN-US" style=""> LDR R1, =0x05FA0001 //</span>置位<span lang="EN-US">VECTRESET<o:p></o:p></span></font></p>1 }' Z5 o' N' |/ G8 k
- ! m) ?2 K. S, g1 M: e; H0 k- h
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> STR R1, [R0]<o:p></o:p></font></span></p>
. h$ t t7 \ K/ B2 O2 V/ {1 b - , U5 Y2 E. |# q7 L# w
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> </font></span></p>" H( D# l% y3 d% i* }0 C2 U# Q" j% v
- 1 C3 J; L7 W8 M2 Q) K- q% T1 Y
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">deadloop_Core<o:p></o:p></font></span></p>
5 Y8 Y: s; g, z' S6 d - 3 i! _5 v1 k9 c" L: g4 C& y# p
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> B deadloop_Core<o:p></o:p></font></span></p>8 j( ?8 r- c7 j( `, G
- 8 D ~5 d& f- F Q; z
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">}</font></span></p>
复制代码 4 `" e5 m K u' I, j4 q U
内核主要注意: SCB_AIRCR_VECTRESET_Msk LDR R1, =0x05FA0001 它是和系统复位唯一的区别。 2.NVIC_SysReset系统复位 系统复位是置位同一个寄存器中的 SYSRESETREQ 位。这种复位则会波及整个芯片上的电路:它会使 CM3 处理器把送往系统复位发生器的请求线置为有效。但是系统复位发生器不是CM3的一部分,而是由芯片厂商实现,因此不同的芯片对此复位的响应也不同。因此,读者需要认真参阅该芯片规格书,明白当发生片内复位时,各外设和功能模块都会回到什么样的初始状态,或者有哪些功能模块不受影响(比如, STM32系列的芯片有后备存储区,该区就被特殊对待)。 大多数情况下,复位发生器在响应 SYSRESETREQ 时,它也会同时把 CM3 处理器的系统复位信号(SYSRESETn)置为有效。通常, SYSRESETREQ 不应复位调试逻辑。 这里有一个要注意的问题:从 SYSRESETREQ 被置为有效,到复位发生器执行复位命令,往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。但我们的本意往往是要让此次执行到此为止,不要再做任何其它事情了。所以,最好在发出复位请求前,先把FAULTMASK置位。因此,我在提供源代码中有这么一句:__set_FAULTMASK(1);,也就是置位FAULTMASK。 C语言版函数: - <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">void NVIC_SysReset(void)<o:p></o:p></font></span></p>5 m) O; e: |7 o" ~1 K6 v
6 _1 c7 G; N2 n4 k' R" r" o+ u- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">{<o:p></o:p></font></span></p>
. F0 u! s6 `9 R f8 X+ u. l& x N6 Q - , a4 S/ V' }! } `* Q
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> __DSB();<o:p></o:p></font></span></p> Y1 y2 o; h7 f6 ^0 \, U% B
- ; Y z0 K6 d1 S# P
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> </font></span></p>: R! i/ p' x e1 P- M
+ K) l% O8 k" A5 h# k# [9 y# K- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> SCB->AIRCR & b2 H; i# W7 h" d% F& i
- = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |<o:p></o:p></font></span></p>6 o1 @3 B% k7 p9 b
; X1 s! a2 ` d- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> (SCB->AIRCR &* W( h4 ]# j: `2 P6 u9 u; M
- SCB_AIRCR_PRIGROUP_Msk) |<o:p></o:p></font></span></p>
* |0 F" r+ {1 W& b4 W- `" E
" M A9 { R; n8 _2 y+ Z- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> SCB_AIRCR_SYSRESETREQ_Msk);<o:p></o:p></font></span></p>
, r6 Q# ~2 R0 e" j! o - ' n( y" T( E+ @
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> __DSB();<o:p></o:p></font></span></p>" w7 J, e& u: Z
! ^; H; h5 x# a/ V- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> while(1);<o:p></o:p></font></span></p>* G; V" F0 ?6 x' \
+ A- m; r$ z6 z. o- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">}</font></span></p>
复制代码 % w5 v" p( o7 s, b
汇编版函数: - <p class="MsoNormal"><span lang="EN-US"><font color="#000000">__asm void4 P0 p3 x3 C& u3 b& h
- NVIC_SysReset_a(void)<o:p></o:p></font></span></p>
1 v- g! s$ ? P% [3 {1 _; F( O1 w
/ @7 u: H0 D+ s e: M( @- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">{<o:p></o:p></font></span></p>/ D( m; M1 u- H; ~ W9 \+ t/ c
0 O; ]- D4 ~% V2 a* j- E2 z- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> LDR R0, =0xE000ED0C<o:p></o:p></font></span></p>
, c' a5 A1 p$ A8 z0 K; d - , w" I4 N; l) v- V
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> LDR R1, =0x05FA0004<o:p></o:p></font></span></p>; P* i1 f# h0 z: x. k* Y$ V
/ z4 l2 V! e5 N; d' |- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> STR R1, [R0]<o:p></o:p></font></span></p>
3 ?0 C) _2 L" h( ~& |) a8 g
6 E2 e7 b Y+ h9 r* W- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> </font></span></p>: {# n, G6 f4 e: B
- " p7 @) L" o: ~; g
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">deadloop_Sys<o:p></o:p></font></span></p>( o1 u7 K, a4 a8 k
' z0 E5 ^1 \/ ?9 c' s4 }- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> B deadloop_Sys<o:p></o:p></font></span></p>6 V0 Y3 y( i1 |4 x2 w
- 1 s+ Z. M% I4 j1 p
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">}</font></span></p>
复制代码
0 b1 I* b: U8 l: ^* ^ 内核复位与系统源代码和相近,差异在于SYSRESETREQ和SYSRESETREQ这两位。 关于复位的知识,在实际项目中应用的比较多。 可以结合上面提供例程理解,以及结合Cortex-M手册理解。 . ~! t" s, V8 ]6 w5 ?
文章出处:strongerHuang
1 b: [3 ?. t: s# k2 M |