一、独立看门狗(IWDG)基本知识+ l p0 S. i5 B* m
1. IWDG简介2 a/ u) b4 C0 @9 w+ R
独立看门狗是由专门的低速总线进行驱动,即LSI总线(时钟频率40KHz),它可以在主时钟故障的情况下仍然可以工作。
0 P7 C# l3 [5 q7 u( I* j3 o独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。
, h8 A5 G+ ~- N+ w$ @ R; e2. IWDG功能描述; ~/ @2 c7 X( c$ T- v- O8 ^+ Q* ?
在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET)。
% K6 L2 E- r2 v4 ?1 q+ _无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗), 自动重装载寄存器IWDG_RLR中的值就会重新加载到计数器,从而避免产生看门狗复位。% t! F( @4 D% J1 e: T( t* u
如果程序异常,就无法正常喂狗,从而系统复位。
' s0 Z. t b. {! d: Z9 s1 m, j! ~( j: b5 B6 v
3. IWDG寄存器3 U) {5 ?: [$ A9 ?9 g- M
STM32中文参考手册中关于IWDG寄存器的介绍如下:# G" s- Z @& c
: q, d: `2 L. _/ O5 {3 |. P& p
8 r+ B% X4 [. V7 J$ s/ J! L% R6 ]9 n9 e: E
" h1 g7 I [- j$ X
8 @1 [/ [; E& G
2 c) `( Y3 B% k5 u6 c, T0 t# b: ^
- c% v" S% X! o. s
( \( O6 w6 O5 _. l* W
& _: j7 }# e+ h
) y5 V; H7 f- H. @3 s; x# K& j+ G8 B. q
L* j; v n6 ~2 W8 V
4. IWDG超时时间
+ L A7 p2 R; b5 c+ \STM32中文参考手册中关于IWDG超时时间的介绍如下:6 h8 I3 g3 F. r$ j
! ~+ t8 W$ w1 h
V5 o! c: d/ }0 E5 ^$ v: Q
/ Z! d/ d5 \$ K+ w2 K! |$ N* y溢出时间计算: Tout=((4*2^prer)*rlr)/40 (ms)
! z* |" b c9 k- y* U: ~prer:预分频系数:0~7(只有低3位有效),由预分频寄存器(IWDG_PR)设置。
+ W3 y# j$ x8 `& _5 xrlr:重载值:0~4095(低11位有效),由重装载寄存器(IWDG_RLR)设置。) }( q$ h3 t: r3 W" Z2 s. _7 Y* j0 f
6 r* A. M4 b# r
二、独立看门狗(IWDG)程序实现
7 r `0 k. S1 T, k" @ V1 X1. IWDG相关库函数" L& o8 J# b8 b
- void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能: C' [' D0 ]$ s/ z" W" ^* _
- void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置预分频系数:写PR
+ w+ H3 ]4 p& f. c% E. T - void IWDG_SetReload(uint16_t Reload); //设置重装载值:写RLR$ T3 H# C3 a' B& Q, u9 s, Z+ [
- void IWDG_ReloadCounter(void); //喂狗:写0xAAAA到KR4 Q1 o& Q1 d( z1 \4 p
- void IWDG_Enable(void); //使能看门狗:写0xCCCC到KR
复制代码
1 I3 E: M& x7 e% R9 W# O: ^2. IWDG控制程序
! w: p! K( u; L1 u. e+ M* G2 ?iwdg.h" y0 \/ w2 \* }, c3 ^& `$ _
- #ifndef __IWDG_H
4 S {0 v0 V# J' I3 W - #define __IWDG_H # {( i3 o8 D5 |5 ^% v6 X1 q( w
- 2 J; D9 L7 S1 c t. I% C' x
- #include "stm32f10x.h"
! P0 v3 |2 v @( i. L9 f
! n: Z Z O6 f0 X: i- void IWDG_Init(u8 prer,u16 rlr) ;
8 v9 ^ L% Z+ q& S+ n - void IWDG_Feed(void);
( X5 q9 T+ c3 ]7 X- L |
. @; w: e( O# A! P- #endif
复制代码 8 n% c1 D8 m6 n; H# B/ ^" {
iwdg.c" Q5 l3 i/ @+ Q' @2 a* @
- #include "iwdg.h"
3 f* l9 ?, N* e( s7 k, V! c - % U; j3 z# M: x' ]: ^ U8 U
- /*******************************************************************************
- y$ D) C- E3 H( g6 Q2 F( x- t - * 函 数 名 : IWDG_Init0 p" K4 R o' w" k! `" D
- * 函数功能 : IWDG初始化& j7 I! P. }1 ?( M& e
- * 输 入 : pre:预分频系数(0-6)
0 ^5 @5 w: l" j! ]0 J0 m - rlr:重装载值(12位范围0xfff)
/ X* G, T& d- E - 独立看门狗复位时间计算公式:t=(4*2^pre*rlr)/40 (ms)0 x4 c% Q( m& j3 {" w( z
- * 输 出 : 无
5 _0 v" n5 h, _4 |( z - *******************************************************************************/
) x* g" R8 ] a* D0 `, Z$ L" o - void IWDG_Init(u8 prer,u16 rlr)
: z7 k% p, b' ?' [( m - { 3 k) l$ o/ B8 q) m
- IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作,即取消写保护
- r2 a( z; A, Y( N - IWDG_SetPrescaler(prer); //设置IWDG预分频值6 E- k- g" R7 q1 u5 d6 m
- IWDG_SetReload(rlr); //设置IWDG重装载值
6 E+ Q3 z/ y D- L0 h6 ? - IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
/ j) s, q' }8 J - IWDG_Enable(); //使能IWDG. ~3 O( N) R X' a ]' ~
- }
$ e7 z7 c: |; v! o* e) g
: g) C/ D! ^5 G/ i8 Z- //喂独立看门狗
. t- I) M: l0 v8 n+ y - void IWDG_Feed(void): k( T1 O. V1 {3 l. ?! ~2 m
- { 8 _6 y0 P& w, l& d- z$ i4 G, y3 _5 B
- IWDG_ReloadCounter();//重装载初值 $ u! r$ S+ i) [/ x+ P2 K# |
- }
复制代码 1 \! V* W" @! D; G# Z# F7 s* L
main.c
8 O3 R$ y% |6 W! w9 ~' D# D* a& G- #include "stm32f10x.h"% v2 K5 e2 V; s5 u3 k
$ u; r( c( O( k% @( H/ M; }- #include "iwdg.h"
: ^: s: H: p3 H3 S9 Q4 y3 c% ` - 1 I6 x. V8 V$ i V4 f. t
- int main(). S6 r6 I5 x/ b/ L1 d# l
- {
! P. o+ N' l$ M - /**1 p. W z& o: [, K
- 其它初始化省略
+ S6 t+ V! U3 |& X1 d' p - **/# H+ |* E/ j$ o/ s, D% n& K# w/ v
- IWDG_Init(IWDG_Prescaler_64,625); //独立看门狗初始化,超时时间1s) Z' y k* @) P8 S/ A- J4 l9 F( m
- * _" i2 z8 u3 Z5 A
- while(1)
4 J" L) U, Y" b2 G5 c# R" U) ~ - {
! p9 W# {8 [4 R% |6 S5 K& U- e - /**
1 W! O7 Q8 E2 v% u8 {) D0 V! {/ Q - 其它程序省略
: O" x+ O9 Y8 X% J/ e! \: o( o3 s - 如果其中程序的运行时间超过1s,需要在其中添加喂看门狗函数 IWDG_Feed();
1 F6 U1 |/ Z1 {9 e, s3 C - **/) I; h/ }" O$ |4 B; z" R
- IWDG_Feed(); //喂看门狗
- }2 B- s7 Y+ `0 p2 H1 T! M: z - }
% B4 s S8 S3 @. I! P: }" u - }
4 W* K4 w4 |7 N. w, h( E
复制代码
* ?4 \% \' h9 e4 F" g# x, J: \9 {7 v0 Y; i3 c
6 [4 t" V: ^' W3 u3 h
2 j( Q! ~0 o l9 J e: v. l+ t
$ U" b5 n$ P- i m5 d5 V |