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

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

[复制链接]
STMCU小助手 发布时间:2022-6-13 17:17
01. 独立看门狗简介
6 T7 m- y$ b3 n: a' Y5 @STM32F4 的独立看门狗由内部专门的 32Khz 低速时钟(LSI)驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部RC时钟,所以并不是准确的32Khz,而是在 15~47Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 32Khz 的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。
" Q4 p9 L, v; r2 Q
8 o1 ]6 g. Q/ ^/ {1 B. a6 C02. 程序功能示例0 l8 d. Z8 J4 |: W/ F
在配置看门狗后,DS0 将常亮,如果 KEY_UP 按键按下,就喂狗,只要 KEY_UP 不停的按,看门狗就一直不会产生复位,保持 DS0 的常亮,一旦超过看门狗定溢出时间(Tout)还没按,那么将会导致程序重启,这将导致 DS0 熄灭一次。
# b" @/ \% J/ a
4 y. m; A8 y/ z9 ~8 I/ T  n0 D03. 硬件设计% E& A1 a& y+ T5 s% Y
用到的硬件资源有:
% C& |0 o" k) E8 I* ~1) 指示灯 DS0' B6 g  I0 ?3 @6 ]7 P; B
2) KEY_UP 按键+ ]9 `5 ]* }# t) x, P
3) 独立看门狗- b$ T3 j% H2 P, I
前面两个在之前都有介绍,而独立看门狗实验的核心是在 STM32F4 内部进行,并不需要外部电路。但是考虑到指示当前状态和喂狗等操作,我们需要 2 个 IO 口,一个用来输入喂狗信号,另外一个用来指示程序是否重启。喂狗我们采用板上的 KEY_UP 键来操作,而程序重启,则是通过 DS0 来指示的。+ \. [! G) h- [3 p& i, ?# G& h* _

  w( E  n, y+ B; Y04. 编程步骤0 O2 P; f: h. \$ T
4.1 取消寄存器写保护(向 IWDG_KR 写入 0X5555 )
- s! x8 l3 O8 s& r4 E& H. v# P( r+ r
  1. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
复制代码
- L3 Q8 Z5 M9 s* N; G* u0 b
4.2 设置独立看门狗的预分频系数和重装载值
  1. void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置 IWDG 预分频值
    8 R3 w, I9 N/ R  V6 n1 l
  2. void IWDG_SetReload(uint16_t Reload); //设置 IWDG 重装载值
复制代码
+ N, Z' ?, f8 w( T0 X
设置好看门狗的分频系数 prer 和重装载值就可以知道看门狗的喂狗时间(也就是看门狗溢出时间),该时间的计算方式为:
- m: ^! C, Y4 ]) i0 o+ M! A; P2 C  E9 n: Q, L
  1. Tout=((4×2^prer) ×rlr) /40
复制代码

- Z* H- c! R# h2 `" L& K0 s' ~其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值),范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);) J+ l$ v2 V9 I
$ z9 X$ }" N- V. G
比如我们设定 prer 值为 4,rlr 值为 625,那么就可以得到 Tout=64×625/40=1000ms,这样,看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0XAAAA 到 IWDG_KR,就不会导致看门狗复位(当然写入多次也是可以的)。这里需要提醒大家的是,看门狗的时钟不是准确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。+ T! w0 p# D8 G/ b' c

/ Y, q9 c# S0 G6 r! Y4.3 重载计数值喂狗(向 IWDG_KR 写入 0XAAAA )- [. g9 h; K0 @7 a' \- ~
; D- c/ E. d5 K2 n2 j* O
WDG_ReloadCounter(); //按照 IWDG 重装载寄存器的值重装载 IWDG 计数器
/ Q/ K6 P2 p% ~4 V. |. O% Y, q* T1 V% h! A1 L
4.4 启动看门狗(向 向 IWDG_KR 写入 0XCCCC)1 @! S: M  v. l* B- V+ m
+ G0 x: v& _( Q: c& r
  1. IWDG_Enable(); //使能 IWDG
复制代码
- _# j1 X2 n' c: e( r3 W+ p, e8 ^
05. 程序示例) n; x' J2 U4 ~! h3 ?
iwdg.h文件
  1. #ifndef __IWDG_H__# D2 c2 ~4 F! H' |+ N
  2. #define __IWDG_H__
    " ]- F+ x9 x; C9 i- c% z# g/ o
  3. 0 X; l* {/ P- D! D, R/ {! U2 {( a
  4. #include "sys.h") E6 n4 @) Q% @  H' p
  5. 2 G1 e" f4 [! j# A  l# s  ~9 M
  6. //看门狗初始化
    5 x7 W# I2 F+ {* ^6 h: T- |' F
  7. void IWDG_Init(u8 prer, u16 value);2 a9 u  ^! c: I* s( U1 E
  8. 4 |; a# [+ X9 R& K
  9. //喂狗& o7 b1 G3 t  S' t# b. X* J
  10. void IWDG_Feed(void);
    ! a1 S8 `  r* j% ]0 y/ D

  11. ; G9 R8 [0 P2 @! @0 A
  12. #endif/*__IWDG_H__*/
复制代码
' I+ k; ^& Q  i# _
iwdg.c文件
" I* Q6 }; V' U3 l# q2 H
! a" j, O0 |. m: J% U7 d
  1. #include "iwdg.h"; W( N1 I/ ]- r  O) B
  2. / L0 Z3 q9 a+ E# p
  3. 6 c2 m6 x: z/ g, d3 x1 Z( q
  4. //看门狗初始化: A5 k: h8 R+ |) K9 T" q7 s
  5. void IWDG_Init(u8 prer, u16 value)
    % j4 l( ~! |" O& W) b5 p6 {
  6. {# m( [/ f9 E3 a" \. i+ y
  7.         //取消写访问保护
    * y, f- Z2 c* A" i; o* @! B% p( K5 L
  8.         IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);. N/ b' g6 A! D1 T+ S  e$ A
  9.         
      i, u/ Q1 p; ]$ ~: ~! [
  10.         //设置预分频
      r+ h+ o' h" x+ g% ]
  11.         IWDG_SetPrescaler(prer);5 E9 K4 |/ K# v* S. t  h* t4 C
  12.         
    , l4 @. u9 J( W4 Y, S- _1 F/ ]0 b( i
  13.         //设置IWDG装载值
      h# F* w# R* a
  14.         IWDG_SetReload(value);( T% n. A" |: X$ f( {- J- j
  15.         
    . i7 q$ Z7 `4 D" E' O
  16.         //重新装载" f$ u9 h/ ?$ W# p7 p# x$ I
  17.         IWDG_ReloadCounter();1 H5 q; f% @1 |* ^
  18.         - z4 \8 V& ?0 _5 k- ~7 V
  19.         //使能看门狗
    * b3 l; p1 B, A1 L& g
  20.         IWDG_Enable();/ O0 r8 U2 q2 h
  21.         
    3 H5 }1 P% b4 I/ v3 A) D
  22. }, N! k+ g" _: U
  23. 6 {6 v; ~, m' T
  24. //喂狗! f' L, J: S0 I' N& d1 f& b
  25. void IWDG_Feed(void)
    $ u* o3 ?+ ]1 o! T; C  V
  26. {        
    6 c7 w1 l& Y- [' `/ j- }' Z
  27.         //重新装载
    & A1 w7 d; k1 p8 |/ m, X, M+ \
  28.         IWDG_ReloadCounter();
    : J5 M; i( D% i+ l$ ?5 {- O: ]
  29. }
复制代码

6 J; V- D2 |0 ^7 @main.c文件7 N( ?, f) J, I8 e% v, V

) T( v, P) t' ^" f
  1. #include "sys.h") N& Q8 Q+ k# X: a: ~
  2. #include "delay.h"
    - i- u8 o8 J5 D. p/ G
  3. #include "usart.h"
    ' G+ m+ O5 F* _5 E# [" M  }* Q9 h0 g
  4. #include "led.h"
    1 C) A, e+ a% a4 @' E4 t
  5. #include "beep.h"
    ( d6 O& e2 l3 V9 D$ V6 v6 u
  6. #include "key.h"2 d( M: _' ]# N1 _" G$ K  y
  7. #include "exti.h"
    , T) L7 _' x# d) v3 Q
  8. #include "iwdg.h"4 H- x. b# a3 o, |6 T  R
  9. ( j, U+ c, a, {6 A/ Y" j
  10. int main(void)
    0 O2 b" P+ L+ f7 Y
  11. {
    - {- F% F' w, T; a( l9 V# E% i
  12.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);3 b4 R' @/ n: N! c  J6 C
  13.         
    + d3 b5 c5 l0 [0 I7 l7 J; F
  14.         delay_init(168);
    + k0 r# Z- e" T7 V' c
  15.         LED_Init();$ T/ j$ a& N% Z' K1 h" `
  16.         KEY_Init();5 y* k5 C0 |3 H- E1 R1 H
  17.         uart_init(115200);- F% k) d/ Z" c, `  ?5 {! I4 y
  18.         
    " `  y4 G* X8 D6 _6 N
  19.         LED2 = 0;
    , h$ b& t  y) B* L2 m& g- E/ \
  20.         
      b1 @3 ?" g7 H  ?) I, m
  21.         delay_ms(100);
    9 S6 R5 H3 t4 \1 A+ k0 B. L
  22.         
    / R* L7 R* v5 a( K
  23.         //大约6秒
    * p* `9 ]1 h2 r$ {8 d# d
  24.         IWDG_Init(6, 500);( m9 z' V7 h+ ]. [
  25.         $ L5 H. ?+ W: e: G
  26.         printf("程序初始化OK\r\n");% q# X9 k9 b% s, _3 V- |
  27.         ( k* F2 F0 m7 C6 B- R
  28.         while(1)/ \8 `: ]& G3 B" E7 s, a! G
  29.         {$ w3 @2 i: l0 t( I* Z3 o
  30.                 if (Key_Scan() == WK_UP_PRESS)
    8 v$ a7 j$ h6 D" K6 p% C# R
  31.                 {6 R- ?: [& j. C- b! G- ]
  32.                         //喂狗
    ' B% S# v7 _/ z% u& r7 h0 B( O
  33.                         IWDG_Feed();# U& D$ t3 k4 ^4 G. R4 G( B( z$ _
  34.                         printf("喂狗\r\n");9 V) m# {. c5 F$ E' J- ]- J
  35.                 }
    2 s2 I+ L( N% e& u5 y3 \7 L
  36.                
    7 b4 V* Q5 K$ Y
  37.                 printf("while do work \r\n");        . C8 @7 o2 j) l( Q
  38.                 delay_ms(1000);# Y; D5 `- a0 O1 L# {
  39.         }        
    8 M  J" T; V( A" R; T
  40. }
复制代码
2 a* v; T" B1 k3 M6 |5 x4 b& ]

- p$ }; f6 b7 ~/ v, x' t: N6 }9 `3 ?
赞 收藏 评论0 发布时间:2022-6-13 17:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

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