STM32复位来源,以及系统和内核复位区别
) C! o$ c0 ~6 H/ n$ ? k/ r. |最近有朋友问了些关于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 ) _ 复 位来源(寄存器版): 8 i1 J% O+ m) r( T% Y5 m# \
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> y$ Z( {. y3 f) `
- 9 f- D. h% y7 L# F4 U- q! I
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">{<o:p></o:p></font></span></p>/ T, J6 v e7 N/ p! n
7 z! _' j7 o- _* T- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> __DSB();<o:p></o:p></font></span></p>" p: ] ?; _+ I( Q4 Q8 }$ V0 x
" ]7 o, E! z* b0 {! c: n6 t+ t- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> <o:p></o:p></font></span></p>- ^2 U7 ^- w. n' M: v
- 7 [# _/ Q* g4 y
- <p class="MsoNormal"><font color="#000000"><span lang="EN-US"> //</span>置位<span lang="EN-US">VECTRESET<o:p></o:p></span></font></p>1 R2 N2 s- e. u
6 x. c7 F: F4 F" F; @/ p( ]3 D- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> SCB->AIRCR ! x$ p& }. }1 O/ u6 X) Q! _5 f
- = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |<o:p></o:p></font></span></p>
3 k0 E- j+ h8 I! ?# B0 _7 z, V8 u - 8 }) `7 Q9 v( r% T( u
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> (SCB->AIRCR &
" y' y% e6 o* E& n! o% n0 o - SCB_AIRCR_PRIGROUP_Msk) |<o:p></o:p></font></span></p>: d6 S: z/ G l8 G( S' r
: s' C! b* m# ?: J1 D3 G; U. M# P- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> SCB_AIRCR_VECTRESET_Msk);<o:p></o:p></font></span></p>
2 B# }) D; q- l
s2 p( P. C ^" _. Y% B6 u# V) e- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> __DSB();<o:p></o:p></font></span></p>, ~& t0 a; k+ ?
- ) a- I$ T0 t, G" d
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> while(1);<o:p></o:p></font></span></p>
( X1 S. ]) m4 \. _, E
6 i+ J/ t, g4 C2 Y. ? w3 i& e! i; t- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">}</font></span></p>
复制代码 * U7 E$ _1 K) i9 G
汇编版函数: - <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">__asm void4 Q1 w- p- `2 l* B
- NVIC_CoreReset_a(void)<o:p></o:p></font></span></p>( r# q' D' Z7 E1 z
- 0 d0 P5 ]% d' p6 D9 m; U+ N
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">{<o:p></o:p></font></span></p>. [: F) n2 C3 P
: t$ A) _7 A n4 c- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> LDR R0, =0xE000ED0C<o:p></o:p></font></span></p>% G% S2 l- b# u, a% n: g1 O
: V6 ]# D, d6 q1 Z- <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>% S6 T( Z9 Y0 K" |2 k9 L+ X$ N
' F' ^$ s% l* l, H9 m- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> STR R1, [R0]<o:p></o:p></font></span></p>! B2 L5 k) e8 z8 R4 L( m, X
& U) X7 P3 V9 K! I, D- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> </font></span></p>6 I/ b; q8 y* W
/ b# m! h; n: ^9 g- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">deadloop_Core<o:p></o:p></font></span></p>
6 i9 z. p0 ?8 \$ i
k9 a4 |5 ]$ G" }/ r* F9 b8 N4 Z- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> B deadloop_Core<o:p></o:p></font></span></p>0 V' k2 c& i; G; k: Z* }& M+ H
- 2 o! p+ t! Q; g2 a
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">}</font></span></p>
复制代码
$ d% j2 |: K( J: g) c, j 内核主要注意: 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>
2 E9 Z) C! \0 C( a4 x$ H - + m1 w/ x& f, K, W+ c
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">{<o:p></o:p></font></span></p>
9 b0 E) s8 s( ~; R* h) W1 l
& C R6 c9 \, f( ]5 q5 D3 b6 ?- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> __DSB();<o:p></o:p></font></span></p>
& J: ]4 {' B2 d3 `( m8 E T! F9 S
6 N. i u1 e+ r8 k' o w$ \5 r$ N- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> </font></span></p>5 b2 u6 S! J. Q- f8 g( L" `
3 w M6 D0 \& @. I' [9 \- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> SCB->AIRCR
0 z: S$ \. W) J0 m% I2 g6 v - = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |<o:p></o:p></font></span></p>7 V# X" O2 |( K8 R- o4 G; @& u
# w/ F7 q5 [4 N3 _* I0 D2 t- s- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> (SCB->AIRCR && N9 e Y% f$ ?. K; M; w; ~: Z
- SCB_AIRCR_PRIGROUP_Msk) |<o:p></o:p></font></span></p>
0 X1 o, ]1 A- I- G7 ~ - ; W6 }; @$ v! k- a5 [" f
- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> SCB_AIRCR_SYSRESETREQ_Msk);<o:p></o:p></font></span></p>
7 @( h) q7 U8 ]8 S u
7 D- r( ]. u2 O6 Y2 u s) P+ m- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> __DSB();<o:p></o:p></font></span></p>
1 y% R8 x: x1 F
. i4 m! D9 M* e4 _# t$ |" |- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000"> while(1);<o:p></o:p></font></span></p>4 N; e* D" A$ i1 ?7 Y
8 u4 H- ^1 K# g, p8 r9 ?- <p class="MsoNormal"><span lang="EN-US" style=""><font color="#000000">}</font></span></p>
复制代码
( p) t# f3 i$ T+ L6 | 汇编版函数: - <p class="MsoNormal"><span lang="EN-US"><font color="#000000">__asm void
6 V1 ]/ K! V; t8 j; [ - NVIC_SysReset_a(void)<o:p></o:p></font></span></p>
& D. x q% A9 M5 P, L8 L- I - . B1 O4 H7 `: H! h0 q' N, |$ M
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">{<o:p></o:p></font></span></p>
! W6 ~3 E7 }1 _- a' {( w9 B
3 A Z" P# x# u' L- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> LDR R0, =0xE000ED0C<o:p></o:p></font></span></p>
$ i3 l1 E% j- a' F4 \' b - ( h1 r, \2 {0 M- u
- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> LDR R1, =0x05FA0004<o:p></o:p></font></span></p>! J6 Z# x/ E* z* Q4 o/ w& V3 ~* }# s7 ]
5 v2 ?( a/ E0 B( ]6 v- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> STR R1, [R0]<o:p></o:p></font></span></p>
& i, p3 m5 s& O: }
8 D: G! s2 \$ @( V; o, C- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> </font></span></p>+ s O; a7 }4 h8 S# o$ Y6 T
5 V" c' w, y/ {- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">deadloop_Sys<o:p></o:p></font></span></p>
7 o4 M6 R6 ~! M N+ X: b
& c$ M- X p4 G+ |6 a3 d- <p class="MsoNormal"><span lang="EN-US"><font color="#000000"> B deadloop_Sys<o:p></o:p></font></span></p>7 g! U; ]# S! V- b9 Z
3 O1 T3 h1 i4 Y! s8 D- <p class="MsoNormal"><span lang="EN-US"><font color="#000000">}</font></span></p>
复制代码 " J& g9 G' |5 ~& k
内核复位与系统源代码和相近,差异在于SYSRESETREQ和SYSRESETREQ这两位。 关于复位的知识,在实际项目中应用的比较多。 可以结合上面提供例程理解,以及结合Cortex-M手册理解。 , d$ i0 z' R% o% E# B0 W
文章出处:strongerHuang
A( l4 T1 o/ ?1 [: n6 \ N |