你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 独立看门狗程序

[复制链接]
STMCU小助手 发布时间:2022-6-13 17:17
01. 独立看门狗简介
+ l, ^0 G: i( v% mSTM32F4 的独立看门狗由内部专门的 32Khz 低速时钟(LSI)驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部RC时钟,所以并不是准确的32Khz,而是在 15~47Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 32Khz 的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。! r# [1 I1 S: i2 A; x* c( @

) i1 y! f! f7 K% P02. 程序功能示例) o. ]1 _! x7 v7 D* [
在配置看门狗后,DS0 将常亮,如果 KEY_UP 按键按下,就喂狗,只要 KEY_UP 不停的按,看门狗就一直不会产生复位,保持 DS0 的常亮,一旦超过看门狗定溢出时间(Tout)还没按,那么将会导致程序重启,这将导致 DS0 熄灭一次。; W( k# J2 w" ?  H$ N) m( i$ O

# S% Y" Z) W0 j- w9 Q9 z, J4 C+ X03. 硬件设计
; N8 w' V9 c) U2 _用到的硬件资源有:/ p+ W! A/ D( O
1) 指示灯 DS0! Z$ Z9 R3 P$ @( j6 l- |# g; W8 c& I
2) KEY_UP 按键7 O, V% F  T1 a  N% P7 [7 H& S( V+ w
3) 独立看门狗0 N+ q4 R1 l) {  p
前面两个在之前都有介绍,而独立看门狗实验的核心是在 STM32F4 内部进行,并不需要外部电路。但是考虑到指示当前状态和喂狗等操作,我们需要 2 个 IO 口,一个用来输入喂狗信号,另外一个用来指示程序是否重启。喂狗我们采用板上的 KEY_UP 键来操作,而程序重启,则是通过 DS0 来指示的。9 ?1 v1 x9 @0 C6 k+ n
( G9 ^6 Y# B& a# S
04. 编程步骤6 @9 A0 }' W4 I4 U5 R$ c
4.1 取消寄存器写保护(向 IWDG_KR 写入 0X5555 )) [' N- E/ q3 G- {
  1. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
复制代码
7 K- Y& N( v) L8 j5 s/ P+ Q
4.2 设置独立看门狗的预分频系数和重装载值
  1. void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置 IWDG 预分频值) ^2 {  v( b3 z9 b5 P7 [1 q
  2. void IWDG_SetReload(uint16_t Reload); //设置 IWDG 重装载值
复制代码

! @7 T# R5 R/ e& d& j1 x& R设置好看门狗的分频系数 prer 和重装载值就可以知道看门狗的喂狗时间(也就是看门狗溢出时间),该时间的计算方式为:
, P3 A7 ~3 V/ w0 i2 ]- H* e# S" w( I. t2 ?, b/ t; o
  1. Tout=((4×2^prer) ×rlr) /40
复制代码
& F/ G; h6 i0 ?$ @9 u# d
其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值),范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);
, l* u+ E9 C# l5 ^0 H$ Y+ W( d# L" d  e$ v* C$ X. E0 p& P
比如我们设定 prer 值为 4,rlr 值为 625,那么就可以得到 Tout=64×625/40=1000ms,这样,看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0XAAAA 到 IWDG_KR,就不会导致看门狗复位(当然写入多次也是可以的)。这里需要提醒大家的是,看门狗的时钟不是准确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。
6 F1 f" ]8 t( p$ M5 ~" r5 ~, {2 H% Z) j0 a9 c5 m" _0 F
4.3 重载计数值喂狗(向 IWDG_KR 写入 0XAAAA )
1 G. i$ Y* g, E4 ?( a& O! h% M9 f9 O; z
WDG_ReloadCounter(); //按照 IWDG 重装载寄存器的值重装载 IWDG 计数器1 ]+ |5 Z3 Z9 l  H
: n5 G% Y8 c4 @6 b0 Q' R0 p2 Z) o
4.4 启动看门狗(向 向 IWDG_KR 写入 0XCCCC)2 \% t  F+ z. a0 z' y

" S7 T' b6 ]& k: y
  1. IWDG_Enable(); //使能 IWDG
复制代码

7 B  [* R+ [: d, K9 Z# G3 z& }05. 程序示例
& s7 m; e# ]7 J% F+ liwdg.h文件
  1. #ifndef __IWDG_H__
      _- b; r5 L$ V1 H3 J+ Y
  2. #define __IWDG_H__* Q& o1 M' `& M
  3. 8 ?4 n- b0 X# O6 W7 u
  4. #include "sys.h"  ]3 z# h8 l7 L( [

  5. ) s5 j: U% h' @1 i
  6. //看门狗初始化
    . L& Q( s: Q6 g
  7. void IWDG_Init(u8 prer, u16 value);. H" x3 B- z; X) I) J! J

  8. 6 f- v) ~0 Z9 ^6 x- ?* s" K
  9. //喂狗! P: I+ {/ i' V7 L' M
  10. void IWDG_Feed(void);
    % D9 _3 \" b* J" _1 {5 w; h$ P
  11. : I" D2 }& d& |- x% J
  12. #endif/*__IWDG_H__*/
复制代码
( z* K5 q; [" @7 u$ l: g
iwdg.c文件' A# E; J& H8 H- e) y3 a4 X

8 G3 Q2 G8 L  z6 W& _
  1. #include "iwdg.h"
    ' z- h0 J# t* b. B$ k" f2 P
  2. $ X1 a2 K7 T+ Q

  3. 0 M" T4 N0 n. f
  4. //看门狗初始化
    # |5 k; s3 t- f$ @" w0 ]
  5. void IWDG_Init(u8 prer, u16 value)
    ; n1 C/ Y% E. C. [; U
  6. {
    ! o) i. U: W' ~' H2 O  O0 A
  7.         //取消写访问保护
    ( N2 T$ S$ N9 }: X3 u: ~
  8.         IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);* T5 N' ?# f: V% v7 J, Z9 S4 x
  9.         
    ) S. ]9 v* m/ i! x: A# I
  10.         //设置预分频+ Y" _9 o1 x" A1 r0 _1 t
  11.         IWDG_SetPrescaler(prer);5 e* c: Z% I* P0 m/ G+ h  C
  12.         6 C% c& I2 v- r% O3 r- ]6 ~
  13.         //设置IWDG装载值
    & d* E) x" v$ l4 q3 V, K6 s
  14.         IWDG_SetReload(value);* K" ?/ m7 H! K8 a3 i" |2 u0 n
  15.         
    , ]* d# |1 k% P5 n# K
  16.         //重新装载6 F; w# ?& Y8 a+ v) Y# ~
  17.         IWDG_ReloadCounter();
    : W! x9 e. H3 H6 }: i7 h
  18.         9 d9 r! A& r6 p: A& l
  19.         //使能看门狗  n. k$ E# x6 L: F& S
  20.         IWDG_Enable();
    ; I* t. m* z+ W0 U. |$ _
  21.         
      J, M2 [4 K( X0 L# I# f
  22. }
    8 r# p6 D( a+ I

  23. . |9 q1 _* g$ l+ G3 t
  24. //喂狗: E, N9 i* V6 p& N. j* ]
  25. void IWDG_Feed(void)0 H3 l# d/ }3 a
  26. {        
    6 N: s1 \. z; x  U- T7 Q/ D! @) u
  27.         //重新装载
    ; }+ }. W, }2 X3 z, x' G5 d  o
  28.         IWDG_ReloadCounter();
    1 v7 j, [* ~- L% R3 o: v8 e- w4 }" f
  29. }
复制代码
! {0 k) J$ c; F2 R' h/ k2 S6 v
main.c文件  Q* Y' |4 r, n: \1 W
1 G6 k5 _+ [. X3 K$ W3 u) a' }9 ~
  1. #include "sys.h"! m! v1 c- s2 Z% ~8 S6 Z( K$ n
  2. #include "delay.h"
      ?$ \0 I: {. p3 X' X
  3. #include "usart.h"5 m0 \$ E% ~" f
  4. #include "led.h"
    3 a; d& l9 d/ |& Q; W
  5. #include "beep.h"' Q; i# k/ ?9 `, n  y
  6. #include "key.h"5 Y0 ?4 Y7 T  I& w
  7. #include "exti.h"
    - u& P1 P' [" J
  8. #include "iwdg.h"; j0 w5 b6 Y. E0 e2 C: j% C
  9. - N$ m) k# S% N& f' E
  10. int main(void)
    * s) J, |# l, y& p7 P$ D3 z) u2 `
  11. {
    7 I" [6 W- S3 t4 {% ]8 ^( H
  12.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    ' A5 s6 a5 A8 _$ _, R+ R
  13.         
    ! G7 S5 Q- a+ [& D
  14.         delay_init(168);
    % T) @1 x4 `& I3 u
  15.         LED_Init();
    $ \; Q, \+ h$ H% ?8 X
  16.         KEY_Init();
    8 O, R/ A; _3 B& m
  17.         uart_init(115200);
      t' C3 j" u  a: s
  18.         " K' ^" v$ ]1 A+ j4 X) q
  19.         LED2 = 0;
    # ?; S! t3 t6 ?+ l$ g
  20.         3 A7 e0 d& z; }' r
  21.         delay_ms(100);. x) ]7 J9 m7 S2 x" i& u9 F
  22.         
    ! ?# X, N; e4 |" f$ X1 c
  23.         //大约6秒) w9 P# l8 g$ f, [5 E0 S
  24.         IWDG_Init(6, 500);
    ' r  o0 M, ~( U( \" j. v9 R
  25.         7 ~( [# q8 y$ X/ x) v4 X
  26.         printf("程序初始化OK\r\n");3 s# ~: T, J5 C' d7 z6 X  w
  27.         
    , f) l* o& `& T. l5 C* ]3 T
  28.         while(1)
    3 e/ P1 s  u! _. h3 d
  29.         {+ M5 X/ r5 K& z  C. c
  30.                 if (Key_Scan() == WK_UP_PRESS), P) R* q7 i- b" x2 W6 J! r1 z3 f
  31.                 {6 g) q4 L# ]4 @% B3 J/ {) S7 D
  32.                         //喂狗
    ' W# A* J* z6 k8 W  S
  33.                         IWDG_Feed();# ]/ ?, {: V6 I
  34.                         printf("喂狗\r\n");; I$ `+ V3 {, Y* a2 [5 H
  35.                 }0 x+ e' d# W! L7 Y2 |
  36.                 9 s, \3 ]! D) E$ I7 Z, e
  37.                 printf("while do work \r\n");        ( Y1 A+ X' t6 G) C$ w+ Q# o
  38.                 delay_ms(1000);
    7 w' G; R/ h. n; j+ s+ T
  39.         }        
    $ a9 h# B1 ^3 x1 \. F" o: ^% j: M
  40. }
复制代码

1 [' h+ ]- |/ R
! q/ T; e# z# D' X, v4 w: {, b. L
赞 收藏 评论0 发布时间:2022-6-13 17:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版