一、独立看门狗(IWDG)基本知识
. O$ ~0 ]! ~$ e/ ~4 r" u6 D9 ^1. IWDG简介
0 K) k4 E$ t4 ~$ o. m' x0 }独立看门狗是由专门的低速总线进行驱动,即LSI总线(时钟频率40KHz),它可以在主时钟故障的情况下仍然可以工作。
9 o& N5 o" H" z% \( I; Y# K独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。
. Y ^5 v0 g3 G2. IWDG功能描述
5 c# ^) ?' a% S4 h0 W% K; t在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET)。
8 R' E; p. J& ]" U1 I) Q无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗), 自动重装载寄存器IWDG_RLR中的值就会重新加载到计数器,从而避免产生看门狗复位。
9 d: b' m, o3 J0 f如果程序异常,就无法正常喂狗,从而系统复位。
7 Z" T8 `' O; S! g2 n" c
$ I1 t9 s3 R% `, r3. IWDG寄存器7 K+ N: ^9 s1 P7 H- ?
STM32中文参考手册中关于IWDG寄存器的介绍如下:
* L0 j( w1 o: z. n! K8 v$ I
6 _! _# h* |# Q3 R. @9 X
1 G; U/ o6 F% N' R5 r; o) c/ g$ T
5 Q: G% j1 o' ]
$ j9 H0 v. p) {: _- B
9 P) O% T! M6 B
% b0 [9 V; Q: F4 q2 w- Z. b* H0 \. c$ a- f& c0 O/ _+ z
! X% E2 C; l7 [# Y
/ F9 B0 ?# ^7 l G Y0 X) U
1 |; p2 z4 f. g2 _' V8 c8 S# K( K \
4. IWDG超时时间
( L9 G0 \ ?! w; C0 o, MSTM32中文参考手册中关于IWDG超时时间的介绍如下:
" ~( C8 g$ R; |: p
. m, U& n5 A/ z. T, |' h3 L
- z+ ?) t! L/ T; e0 q% `# U( {2 h. m% @0 A
溢出时间计算: Tout=((4*2^prer)*rlr)/40 (ms)
7 a& w8 q; ?( W w( v) o$ lprer:预分频系数:0~7(只有低3位有效),由预分频寄存器(IWDG_PR)设置。
5 R) x2 s) A2 c8 y; wrlr:重载值:0~4095(低11位有效),由重装载寄存器(IWDG_RLR)设置。
2 R' B' k1 W" p. [% |& {
6 z4 u7 e$ J, I二、独立看门狗(IWDG)程序实现, n, B8 t- x% @. R8 w4 F
1. IWDG相关库函数( ~5 s& `( I {; P1 Z' `, t
- void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能! P ?* g6 \& Z h( ?4 w* r; N
- void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置预分频系数:写PR
9 U" h! R# ]0 X( b+ ` - void IWDG_SetReload(uint16_t Reload); //设置重装载值:写RLR
! y* J" T5 K0 @. r; ~; K - void IWDG_ReloadCounter(void); //喂狗:写0xAAAA到KR
- _% ]2 m' C& }: {# n4 k {1 D - void IWDG_Enable(void); //使能看门狗:写0xCCCC到KR
复制代码 , I: F0 k* y/ M" O- Y7 r" o
2. IWDG控制程序
+ b- j/ L9 L: X6 X; y4 yiwdg.h
2 _3 O' x3 d! |2 `( o5 I! v- #ifndef __IWDG_H
# Y3 v- t# Z0 M4 @: x8 N4 q s - #define __IWDG_H ( t) O# Z; G& ?* J
7 b1 Z; I ]; n, Q- #include "stm32f10x.h"1 ^( ]$ Y: X+ X6 {2 z1 {
$ h2 m, S; B$ r' q2 H9 o- void IWDG_Init(u8 prer,u16 rlr) ;
5 T2 h8 N1 c) C8 t- }* s' o, Y - void IWDG_Feed(void);
( p6 F2 D4 l- N7 r/ a/ v+ s s1 s - 3 x! @" X6 M2 Y1 |& b' L* H
- #endif
复制代码 : i# V- k7 K7 Z4 m: a
iwdg.c
' X) u* u. Q; q, o' l- #include "iwdg.h"
0 y' T) r% N2 H8 t, y" W# y1 F - 0 p. _ {$ D: e/ w
- /*******************************************************************************
3 Z' {1 k* H8 N W& H' G - * 函 数 名 : IWDG_Init
0 f, d1 a. {. p- y/ L2 j1 b# S; y# P - * 函数功能 : IWDG初始化
# H& V8 b J: U* j. A; M+ O - * 输 入 : pre:预分频系数(0-6)
, u# f) Z4 d" B! i9 Z0 V - rlr:重装载值(12位范围0xfff)
# x$ b# D8 p8 o6 o0 U$ Q% ~ - 独立看门狗复位时间计算公式:t=(4*2^pre*rlr)/40 (ms)
( g! Q* J) d' a& v' U9 N - * 输 出 : 无
! a' y9 w# G+ S! o' d6 U/ f* L - *******************************************************************************/
0 O+ _. I5 M* v+ ^1 ]$ c - void IWDG_Init(u8 prer,u16 rlr)
, f! Z% C" y6 c3 S2 r - {
9 E2 N1 `5 b1 R* L) | - IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作,即取消写保护' M" J& Z% O. |" I O0 y
- IWDG_SetPrescaler(prer); //设置IWDG预分频值' _- \* P/ k. \& X+ I! u
- IWDG_SetReload(rlr); //设置IWDG重装载值4 K- N. B" H+ o- p2 i- u, I" h
- IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器/ x1 P2 c4 R. h7 c. c1 Q# K
- IWDG_Enable(); //使能IWDG
2 ]3 d g2 W9 V+ r' ~* Z1 W9 n( N - }) x# L/ M8 D; U+ @3 Z" X
- ( f1 I) \8 a) k! r v7 J
- //喂独立看门狗
$ C9 J& l I+ y0 Z3 ? - void IWDG_Feed(void)
% S/ W: W q N! R - {
$ q* ^1 k- i( m( D& h - IWDG_ReloadCounter();//重装载初值 " l0 }$ P& V; u* ]+ ]; n h3 ?, v8 }
- }
复制代码
1 s4 A, J1 Y. f, c9 _8 Z2 rmain.c6 b: H6 w, }% N: R2 @
- #include "stm32f10x.h"3 d7 Y/ I7 I2 E' Z, I! p- N. y
- ) l- E9 ?1 ?& I$ O$ }
- #include "iwdg.h"
3 h: j& k. E1 r, w4 S W% B
! `" i: f. N9 G* r- int main()
. f7 D" S+ U# M1 E" k - {
9 l$ P# S9 b6 C5 y' f' ]8 s7 B - /**$ y t- J5 v7 Q) ]! c# P
- 其它初始化省略' `+ f/ ^" T7 @
- **/4 {: {$ i# M$ h- e6 B+ |; M
- IWDG_Init(IWDG_Prescaler_64,625); //独立看门狗初始化,超时时间1s
- Y$ [4 B" ]' z2 z -
1 v8 h- m) c. v - while(1)' V8 S& A9 o, z9 Y7 H6 u
- {: O0 c, h' d1 V+ g5 D% H0 E
- /**/ {' x7 `. d9 i0 }1 u8 h
- 其它程序省略* y u* x/ r: h5 s- S% V& r
- 如果其中程序的运行时间超过1s,需要在其中添加喂看门狗函数 IWDG_Feed();
5 J! ?$ K- v, I, @1 X+ o - **/! g8 I( n, ?- X! }9 I$ L4 z
- IWDG_Feed(); //喂看门狗2 n7 a( i, j& I" M* e9 n$ z
- }3 h1 E7 l# N" j1 e7 d; o
- }
6 R3 h; ^. V- g5 m
复制代码
( Q0 R1 o* ^! P `/ l6 x
+ x; l5 L6 S5 m2 x8 O/ B0 M3 W3 Q* p. U8 H- F
1 ^' c! q8 t! D- p- l5 b
]0 d$ p: o9 M, @0 _+ K
|