一、IWDG简介
+ L2 K+ ~" S |) v' A6 p独立看门狗(Independent Watchdog, IWDG),什么是看门狗?字面意思——看门的,有陌生人来,就会叫。实际在嵌入式领域里,看门狗也是这种作用,当软件程序发生故障或者程序跑飞时,看门狗会产生复位信号,复位系统。
$ U5 q: d' |; J$ \$ g; }% U, j
Q5 Z+ j/ T; T0 l) H- B: L& r二、STM32的IWDG
) z1 v e- B; S, O: D* _2.1 STM32的IWDG简介8 O2 l4 U) G6 o7 ?# R$ R$ \
STM32内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。窗口看门狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。
# {, c5 v, @" d6 G: ?7 d2 E, Z. u/ E }$ N/ m' C. i4 Y
IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精 度要求较低的场合。WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序。
! i0 T+ H2 f7 T5 C. _8 f5 J* r. u3 L$ w( Z8 W$ X. `6 B3 R
• 自由运行的12位递减计数器
" y& K5 X9 `# @: _) S" r1 i2 t5 n• 时钟由独立的RC振荡器提供(可在停止和待机模式下工作)
( J5 ^" d" X; x @% @; h• 看门狗被激活后,则在计数器计数至0x000时产生复位4 _3 _* s* V6 x9 p' o- Q' N5 Y/ U
9 Q6 ^. x0 [+ g& o. F! L一旦使能IWDG,就无法关闭。只有等到复位之后,才能将IWDG关闭。# k2 R- g' Q: b' A% f
/ {$ Y- T7 n+ J
2.2 喂狗$ t- N$ x/ v k4 f4 U: `6 C
通过上面的简介可以知道,独立看门狗实际就是一个12位的递减计数器,当计数器的值递减到0的时候,就会产生复位。但是,如果我们在计数值递减到0之前,重新给计数器赋值,那么就不会再产生复位。这个操作叫做喂狗。
% P" e+ _+ d/ J
; U9 x1 q) `/ n$ v+ [5 |, Y1 C! u2 N
2.3 IWDG框图
* X! q/ A& s' i, N5 b
! ]/ J0 h" X) k0 h
8 j8 }# t/ v$ h
, t7 U3 k1 p8 i$ a8 m2 hIWDG框图 - ]- g6 C8 m8 y4 D0 c* j( ~
# J! T1 e: v3 p$ W0 {/ U8 D
IWDG的框图很好理解,IWDG由一个由独立的RC振荡器提供时钟。经过一个8位的预分频器对时钟信号进行分频。12位递减计数器按照设置好的初始值和输入时钟递减。当递减计数器递减到0时,产生独立看门狗复位。
+ G, @2 Q! [) a" E: F( K8 B* ?& {8 }2 u% D3 l
在产生复位之前,如果将重装载寄存器传递给递减计数器,那么就会重新开始递减,这叫做喂狗。/ D. b/ `- X& X9 ^+ A; K
$ `( `- y' Q, l3 I% u* O键寄存器也叫做关键字寄存器,往该寄存器写入不同的值,有不同的作用5 d, ^$ i2 s- r1 x5 _/ J3 R% x
5 ]5 B& j8 i& ^5 y1 D7 A% k( \
• 写入0x5555——表示允许访问IWDG_PR和IWDG_RLR寄存器1 w* e% S5 Q4 r+ g
• 写入0xAAAA——将重载寄存器的值传递到递减计数器,也就是喂狗- |8 b- |" [0 s$ r3 w! q
• 写入0xCCCC——启动独立看门狗功能- S$ V& S! F: q) {7 c8 t
. A+ }; F8 m8 P- D4 @8 D9 Q! _5 s中文参考手册中给出了一个时间表( J. `+ `0 v/ X4 F! X8 x* H% S
" H8 T2 M" e' X) f9 i6 l
" B! c6 |+ m( d3 q2 f7 N% G5 AIWDG的溢出时间表
3 ]4 H3 N6 R1 z$ a2 Q2 }# c
+ q& y5 g: j3 N6 t4 E
" F n! E9 A# [- I6 H2 L时间的计算方法是,时间 = 重装载寄存器值 / (输入时钟频率 / 4 * 2^预分频系数)' J# w# Z( f$ \4 f; A) I5 D* x
& j; [( h: W D9 \; ?为什么是4 * 2^预分频系数,可以看一下中文参考手册对于预分频寄存器的描述3 m) \7 j9 C1 ?4 H! ^% z
- A0 D" n* U! x1 y* b8 V; U0 Z
% h+ j. B" D- H8 {9 [预分频寄存器描述
) |- a6 b2 Q5 e1 P6 a9 T7 {; ~' ?6 `* c* I
y# ]) L0 k) d/ ~8 ~! N
三、IWDG配置步骤
) ^: }: h+ e3 p• 开启寄存器访问(允许访问IWDG_PR和IWDG_RLR寄存器)
8 a* A1 {) m A6 ]& e• 设置IWDG预分频系数和重装载值
7 N' f" Z3 E7 B7 b• 将重装载寄存器的值传递到递减计数器(喂狗)0 ?3 m) I! ]- Q% t
• 开启IWDG
) L4 h6 ~0 f' \. ]2 h, p. a
& y0 z' a1 m& Y- t
6 K5 d2 a7 ]7 v0 d- n四、IWDG配置程序
. }/ o# h7 B9 q5 h% v44.1 IWDG初始化程序
4 z% Y8 I$ f1 A6 Y( ?0 b5 ?- /*) w3 x: \. d: g; D0 X+ I1 w. c, Q
- *==============================================================================% L/ I5 ?6 N' U7 S2 I- Z
- *函数名称:IWDG_Init
- `, V, ~) w) V0 h+ i% V# i - *函数功能:初始化IWDG
$ _. n* A: y/ w$ z - *输入参数:pre:预分频系数(0~6);rlr:重装载值(0~0xFFF)
0 X h$ Y% _2 E6 `' | - *返回值:无
1 ^: L7 S W$ |% e7 C - *备 注:独立看门狗复位时间计算公式:t=(4*2^pre*rlr)/40(ms)
7 y; w. Y5 E+ I5 {; O* i! x* A5 X' R - *==============================================================================
! E# D3 o, ^/ E - */2 r3 A+ U8 t$ C* z7 K6 b* [
- void IWDG_Init (u8 pre,u16 rlr)
; [ K- V b1 p1 a# ^0 i3 }% b1 }! f! { - {: y9 [- V: L( Q" b) Z/ K
- IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 取消寄存器写保护
) ]2 X5 n& K0 U: b& K" b - IWDG_SetPrescaler(pre); // 设置预分频系数 0-6
4 K1 y+ U2 `$ M( a8 j8 ^4 E" I - IWDG_SetReload(rlr); // 设置重装载值
$ v* m0 }- Z# _- b. q/ V - IWDG_ReloadCounter(); // 重装载初值
! Y, y, S3 [9 Q; S5 K1 T8 r - IWDG_Enable(); // 打开独立看门狗
1 z: H& V. l, x9 H6 W& [# u - }
复制代码 ( J `* e/ e6 O
8 \2 j) y) X' E7 g/ I4.2 喂狗
+ Z) n+ W$ Y) A+ V2 D; \- /*' k8 r$ ^0 F. P4 U; o# q% `# y% J
- *==============================================================================, M6 o% `4 L6 M4 h
- *函数名称:IWDG_FeedDog
3 ?/ v* E8 a! q% _) J/ ?3 k - *函数功能:喂狗
3 o2 l( E+ e6 P$ y$ `0 N2 f - *输入参数:无) O2 J/ {8 G0 [6 J7 Q
- *返回值:无* L1 U1 d4 ?3 S2 V% }; W
- *备 注:无
0 {4 L/ \0 w7 Q/ N+ d. L+ y4 Y: Q - *==============================================================================
( X. ~8 i. _7 g - */
: ~3 K9 j2 t: P - void IWDG_FeedDog (void)
, Q& L9 T" n; X2 y7 X) X x1 L. a - {
1 e( [8 k/ {- M, N# n: J @ - IWDG_ReloadCounter(); // 重装载初值9 v" T* Y& a8 F* D* G
- }
复制代码 $ N( {; f& U- s4 @0 f; }9 n; \7 Y
五、应用实例
( t& u6 Q! @/ m' H# ~初始化IWDG,配置2s内不及时喂狗就会复位。通过按下按键WK UP喂狗。串口打印复位和喂狗信息。IWDG初始化程序如下. W: q$ e# [5 J" J' E, u
- IWDG_Init(4,1250); // 看门狗初始化,2s不及时喂狗,复位
复制代码
9 n+ v+ q6 @0 C' `8 m2 V1 i$ ~! Dmain函数如下7 \ q1 Y7 U) W& r. \
- u8 gKeyValue = 0; // 记录按键键值变量' {: E% q3 ]" w! M1 U
/ r1 ^7 W a! e& Y0 P# v- int main(void)- A# v7 @9 @% L9 L0 E& a3 [
- {: m% X9 H- z) m, M2 Y
- Med_Mcu_Iint(); // 系统初始化
' k; S' O2 H/ i. H, b - printf("复位系统\r\n");
* P6 b+ _* q8 o- ^+ N: Z$ q3 X -
; e7 Q$ V, \$ j% V7 y1 Z' @ - while(1)
- Z& E6 \* n) G" i5 j- K# Y - {
0 B% m% s. [: t - gKeyValue = Med_KeyScan(); // 获取按键键值
: L5 ^" r) j" s& E7 m -
4 N+ M/ @! e9 U9 C6 Y8 m0 Z - // WK UP按下
5 a/ _0 K: \# S7 D1 Z. J+ H6 i+ t - if (gKeyValue == 1)' H; \+ z; L8 P/ p* ^( e
- {- ?. y D& D% u- _5 x- K8 }
- IWDG_FeedDog(); // 喂狗
, P' r! X F- C0 M/ }5 S: ? - printf ("喂狗\r\n");, D, t9 N4 a& r$ J& \3 [$ p% ]
- }
- }8 t/ `- w* X# g) {5 } - }
/ i7 j9 K$ I" X# T5 D7 |' @) b* D - }
复制代码
" e0 |3 G8 K$ O4 N效果如下
5 n& O$ ^' V. l5 R: u
# }8 u2 e8 x1 Z" P! |$ M
- p6 j4 I9 C9 n. D) kIWDG效果
8 x4 m% d4 h# n5 A V7 W8 Q, B. O4 S, T7 l6 W1 R
: A5 M' z: a2 Q% ^按下WK UP喂狗,不会产生系统复位。
2 ~/ L# C/ E3 D6 G
, b9 x, e8 [5 A1 C% D, A7 @) E一旦2s内,未按下WK UP,就会产生系统复位。, {- ]; A; l7 B o( d
: e' H" V7 B0 {
: s: ]% w \3 z F2 v8 ?转载自: 二土电子
' e2 v, ?# U {0 ?3 W. }如有侵权请联系删除2 G$ g( i' x5 J0 U4 S/ }
+ ]# n* j0 E0 w [ X$ I
* h# P2 x ^; J0 d: ]
|