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

【经验分享】STM32F103看门狗功能实现

[复制链接]
STMCU小助手 发布时间:2022-3-19 20:51
  STM32F10xxx内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备( 独立看门狗 和 窗口看门狗 )可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。
( ?) Y. ?8 s+ l# A$ @" [# j! B, r6 K  Q4 R0 X
  独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。窗口看门狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。' s4 P) Q. K! }. _

6 g. s2 t8 g; A$ G  IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序。" U$ t  v+ f. ^6 g$ Q* s5 q
/ n. i- f0 b2 @% W* }
  看门狗主要是用来对系统运行状态进行监控的,以免系统被干扰后代码跑飞了,导致系统混乱。看门狗的使用也比较简单,下面就分别来看一下独立看门狗和窗口看门狗的使用方法。: \6 v/ |- s5 k; g8 T9 T' Z8 X/ ?

3 L, q( q, q- Y( s6 X独立看门狗
: G2 j1 r5 N2 K0 b2 b/ J' g1 a, K1 U8 a  I. J
  1. //初始化独立看门狗
    ' m5 W/ x" D" \, b7 x
  2. //prer:分频数:0~7(只有低 3 位有效!)/ B9 n1 R( k- \( c. d* ?
  3. //分频因子=4*2^prer.但最大值只能是 256!
    % i/ J2 x' o, Z2 l, {
  4. //rlr:重装载寄存器值:低 11 位有效.1 w; N- ]$ c1 E4 P+ M% n
  5. //时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
    $ t) A3 _: y8 I7 O
  6. void IWDG_Init(u8 prer,u16 rlr)
    ) B" p" G8 W8 Z0 d( K
  7. {) g; g' b9 H2 Q& h( |  {; g
  8.         // 1、取消寄存器写保护 写0x5555$ ~2 _$ P4 g5 V: i; e: k8 t5 w
  9.         IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);8 x! s' D7 O. h, D+ g: e/ O3 z
  10.         // 2、设置独立看门狗预分频系数
    $ M% ]- \+ D1 [2 q  I: g1 p
  11.         IWDG_SetPrescaler(prer);0 _, b5 U: M, G! J9 U
  12.         // 3、设置独立看门狗重装载值- C( k/ _/ l- l, a5 X7 D
  13.         IWDG_SetReload(rlr);;  J' }% g9 W3 ~; f
  14.         // 4、重载计数值喂狗 写0xAAAA
    - p6 O, W- b, I6 T- U6 w
  15.         IWDG_ReloadCounter();
    1 {  X, T9 z+ z) U
  16.         // 5、启动看门狗     写0xCCCC# Q+ w4 Y+ x& c' J3 v' X/ K
  17.         IWDG_Enable();
    ; L1 ?/ `2 R# f9 b. \$ F$ _' g$ _
  18. }
    8 \, _/ W* h9 C. @
  19. void IWDG_Feed(void)9 ]- Z( u- |8 c  V. Z
  20. {
    ; C8 m2 m3 S* C
  21.         IWDG_ReloadCounter();
    8 k  t- i) W* G( S* k$ W
  22. }
复制代码
. u" D' R; z# D9 x6 U% e
独立看门狗的初始化很简单,主要就是设置一下喂狗的时间。然后在程序运行过程中不停的喂狗。
; O$ U3 k9 c, h& O& i
( M) I$ p& y3 h* E9 M, r
  1. int main(void)
    + o! ~+ S4 P$ Y0 N* x
  2. {4 S8 X0 _3 R) T5 x
  3.     u8 key = 0;
    ! |! u% u6 f5 Y' p* C/ i
  4.     delay_init();       //延时函数初始化
    ) Y) }- B" v# a( e* U- B; A
  5.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);' [" z& s. o( P1 g3 T% m4 t
  6.     LED_Init();
    & u: r4 N: O2 A. ?
  7.     KEY_Init();! @/ A/ i) V/ i) o1 ~* ?% {$ }
  8.     IWDG_Init(4, 625);        //溢出时间为1s  (4*2^4)*625/40=1000ms9 g4 l9 ^* V: S

  9. " T) @: U$ [2 f
  10.     LED0 = 1;. x) M- A' ?& m' R" D6 C7 }/ v7 V
  11.     LED1 = 1;
    0 n) b5 e0 _5 X0 n7 L2 Z2 ]' I
  12.     delay_ms(500);
    ; b" w9 q5 d. w) f5 ]0 x& b/ N, m4 \
  13.     LED0 = 0;% n# ?( j; G) z
  14.     LED1 = 0;
    5 H# {# T0 a- Z" a7 N7 _
  15. 0 a- x" R4 ]* Q7 w+ |$ @7 A% f/ {
  16.     while(1)4 O. l& K! ?. i2 n" r$ A
  17.     {
    4 U) @$ p4 \! O9 ]% t, c  p
  18.         key = KEY_Sacn(1);7 f- Q% h. {! L. `% g4 c
  19.         if( key == WKUP_PRES)
    3 w3 n  \+ T' ?5 t+ [0 H( c* [
  20.         {* l7 V7 Z  q2 X/ h
  21.             IWDG_Feed();
    : P6 j% u. r) S5 S4 a+ T
  22.         }
    ( Z; F$ j" B3 Y1 T; K1 E
  23.         delay_ms(10);+ M" P0 B  r7 \5 ~) [* D
  24.     }2 q! ^7 @4 D7 T% Y* A
  25. }
复制代码

, G& M3 l, j- w1 j3 L7 N- z5 k( Z+ I1 h这里通过一个按键来模拟喂狗,当按键按一次,就会喂狗一次。如果按键超过喂狗时间没有按下时,独立看门狗就会使系统复位。
& f/ D9 v: ~( v
5 F+ {' F4 K( ^; @: ~4 I窗口看门狗
9 e1 y" r8 O7 v1 ~3 @, X
+ [9 y4 J0 }7 v, q9 k2 F6 L
  1. u8 WWDG_CNT = 0x7f;
      _$ a% h. U# q, M3 l) g3 a
  2. void WWDG_NVIC_Init(void)
    % P! ^& n8 T- G
  3. {5 b2 Q: O- E9 k3 Z) [8 A# N7 g
  4.     NVIC_InitTypeDef NVIC_InitStructure;0 ~; a' \% j; P( ~) B' d0 o
  5.     NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;# Q' b/ K6 d0 z& G: Z4 i
  6.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    8 e  k* f3 }$ q$ l$ A1 }
  7.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;7 b2 Q4 k0 `. L$ s$ m4 w
  8.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    8 N5 `& B5 o9 u9 X# d6 W
  9.     NVIC_Init(&NVIC_InitStructure);+ F+ _* T/ h" {3 L
  10. }# B& z, g) v# Q& D8 ~- H: ]
  11. ) _7 O- U7 Y8 [5 w5 J
  12. //初始化窗口看门狗5 \! l- x: T* O! F# N* ~
  13. //tr :T[6:0],计数器值
      j) O6 o' f# r( h, p+ d1 A" D' R
  14. //wr :W[6:0],窗口值: p. x% |4 W5 b$ l+ v6 q' e
  15. //fprer:分频系数(WDGTB),仅最低 2 位有效% k% v4 ]3 ]- a7 O  l1 b
  16. //Fwwdg=PCLK1/(4096*2^fprer)
    : G, Y: G* v9 ~% c# @, c& m( e1 B
  17. void WWDG_Init(u8 tr, u8 wr, u32 fprer)) B+ y; z# ^: p
  18. {
    " B/ k+ A$ ?0 V1 g
  19.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //时钟使能0 ]" A& i- g: a
  20.     WWDG_CNT = tr & WWDG_CNT;) V3 d6 x; y) p
  21.     WWDG_SetPrescaler(fprer);                        //设置预分频值2 ]& |; Q, D8 V' m
  22.     WWDG_SetWindowValue(wr);                        //设置窗口值 上窗口值  与喂狗间隔没关系* n( n2 o0 x3 Q2 R1 e8 m% i
  23.     WWDG_Enable(WWDG_CNT);                        //使能看门狗,设置计数值( t8 a/ K0 k: y1 E$ f, P& T: G
  24.     WWDG_ClearFlag();                                //清除提前唤醒中断- Y/ C" D7 c$ m6 o& l
  25.     WWDG_NVIC_Init();                                //设置中断优先级" y/ h" o% V9 ]5 ?0 ~: O
  26.     WWDG_EnableIT();                                //开启窗口看门狗中断7 I! c% r+ n" S0 Y; {# ^
  27. }
    8 `/ B9 Q. _1 l: o$ Z. p' v
  28. void WWDG_Set_Counter(u8 cnt)
    4 G* r$ k& _  e8 O+ {
  29. {' z( s$ j( Q4 k& A- \
  30.     WWDG_Enable(cnt);                                //使能看门狗,设置计数值
    / n! Z7 K4 y& q% {/ E6 V3 g
  31. }
    8 o" E6 \; S& i/ h! s' m2 t0 t
  32. void WWDG_IRQHandler(void)
    0 s/ ?! i+ {! p( ^
  33. {
    0 b" B. T) K" I/ s
  34.     WWDG_SetCounter(WWDG_CNT);                       //喂狗
    0 ]8 @8 K. [6 V4 O6 \8 W- q
  35.     WWDG_ClearFlag();                                //清除提前唤醒中断
    ( |0 c7 \9 Y- b6 n9 k9 j3 b
  36.     LED0=!LED0;+ Z0 `" d6 f0 u- V& J% N$ V
  37. }
复制代码

( X( P! q/ t" X* U# F- Z6 P由于窗口看门狗的喂狗时间很短,在程序运行过程中很难判断出什么时候该喂狗,所以这里喂狗使用中断来执行,在需要喂狗的时候,直接触发中断,在中断中进行喂狗,每喂一次狗,LED就取反一次。通过观察LED的闪烁就可看出中断函数的执行情况。* j: [1 L+ r. T! z$ w; ?' Y

9 t+ Z2 D$ }* w5 J$ n7 G, j" Z
  1. int main(void)
    ' c1 f  G* |4 `$ X8 \) A
  2. {& I9 W, E7 e; y* H8 _
  3.     u8 key = 0;
    ! i7 a" Q& j2 ?  T
  4.     delay_init();       //延时函数初始化
    , K: Q" S* a5 x) ]6 _2 I' q
  5.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    / M* o; ~0 a* M3 L- U1 Y7 u  b
  6.     LED_Init();
    1 e( t  }1 c9 j- N' E- F- u9 r
  7.     KEY_Init();
    & N1 d5 V- x/ p" ^
  8.     //IWDG_Init(4, 625);        //溢出时间为1s  (4*2^4)*625/40=1000ms
    . J+ W- z& Z; F: m" Q& ]
  9. 0 W$ o/ ~# ]% ~+ @" i
  10.     LED0 = 1;! u6 }/ b8 b  w7 F! K5 G: d; s
  11.     LED1 = 1;  C8 y; y5 p. P+ l! v! ]% c
  12.     delay_ms(500);* ?$ p, c4 T# B2 v) N
  13.     LED0 = 0;
    . ]* L6 P3 |  |$ f1 e. J
  14.     LED1 = 0;6 A; c$ }# ~2 a" S
  15.         ' h1 C, u' q3 z
  16.     //窗口看门狗喂狗间隔 只和 tr 低6位有关  wr 可以设置为0x40---0x7f 之间的任意值
    0 S' q! N1 q2 F! T  G% G1 p
  17.     // 4096*2^3*64/36000000 = 58.25ms   (64为0x7f 低6位值)5 N1 H6 p/ I0 U0 l2 z
  18.     WWDG_Init(0x7f, 0x7f, WWDG_Prescaler_8); //计数器值7f,窗口寄存器5f,分频数为8
    ! @5 z% V" \; H" `1 m
  19.         
    7 s  s% i- W) @7 x# u  ~, H9 B
  20.     // 4096*2^3*31/36000000 =28.22ms   (31为0x4f 低6位值)
      G1 Q' i* _: n+ O
  21.     //WWDG_Init(0x5f, 0x5f, WWDG_Prescaler_8);. c! I# i# U7 K1 U
  22.         , C" {. T8 H* n6 d
  23.    // 4096*2^3*15/36000000 =13.65ms   (15为0x4f 低6位值)4 Q5 O7 R6 y9 H! {& G
  24.     //WWDG_Init(0x4f, 0x5f, WWDG_Prescaler_8);        
    4 v! H% r  x1 s3 Q% c( `
  25.         
    ) t/ m" A- g; z: {  ^& G% v! p
  26.     // 4096*2^3*1/36000000 =910us  (1为0x41 低6位值)  窗口最小值为0x40
    0 G! Z/ v) i8 l/ V
  27.     //WWDG_Init(0x41, 0x5f, WWDG_Prescaler_8);/ j# D/ V* q3 Y
  28.     while(1): y1 V, {, `% D' R9 X
  29.     {      
    : |* U- S7 `: P7 Y+ o* h) z, ^: R/ c. A6 S
  30.     }
    / L  b- G# E$ E2 |1 K
  31. }
复制代码
; ^, [8 G  |. j/ W2 Q- D
在主函数中通过设置不同的溢出时间来观察LED灯的闪烁频率。
0 b3 [! b8 a) m( u2 w. u* w" ?' t$ I9 B3 R
) |& r- D5 _: L2 f4 \* \
: Y/ G; Z, V/ }2 o* d' i
赞 收藏 评论0 发布时间:2022-3-19 20:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

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