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

【经验分享】STM32G0学习手册——WWDG运用

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:07
概述
! _0 }, x9 C& Q2 h系统窗口看门狗(WWDG)用于检测软件故障的发生,通常由外部干扰或无法预料的逻辑条件引起,导致应用程序放弃其正常顺序。 看门狗电路会在编程的时间段到期时生成MCU复位,除非程序在T6位清零之前刷新倒数计数器的内容。如果在递减计数器达到窗口寄存器值之前刷新递减计数器值,也会产生MCU复位。这意味着必须在有限的窗口中刷新计数器。WWDG时钟是从APB时钟预分频的,并具有可配置的时间窗口,WWDG最适合要求看门狗在准确的时序窗口内做出反应的应用。1 a- D1 |  F# T/ S- K/ k
/ f# o& d' T1 k7 i1 t9 ?
主要特性 ( H8 Z/ T7 S- f, }+ A
激活窗口看门狗后,如满足如下条件则重置芯片:
& D8 ]# Z4 [( l/ z1 d" }# h9 F
* D# _- O7 i8 a5 n4 L当递减计数器的值小于0x40时
6 y6 H7 T( o$ z& i窗口值外重新加载递减计数器
4 f9 i4 i- A4 f8 b% ^如果启动了窗口看门狗并允许中断,当递减计数器等于0x40时产生提前唤醒中断(EWI),可以被用于重装栽计数器以避免WWDG复位。* a  Z9 u' g2 V2 P- k6 N

6 r) j8 D6 G- ~6 N/ X; p% ?用法

! {" G) R# i, _5 {  T0 w+ A如果看门狗被激活(WWDG_CR寄存器中的WDGA位置1),并且当7位递减计数器(T [6:0]位)从0x40递减到0x3F(T6被清除)时,它启动重置。 如果软件在计数器大于窗口寄存器中存储的值时重新加载计数器,则会产生复位。6 y- ~+ ]! y* |/ m- ^

6 D, _. z- d: c6 D0 l  n在正常操作期间,应用程序必须定期在WWDG_CR寄存器中写入数据,以防止MCU复位。 仅当计数器值小于窗口寄存器值且大于0x3F时,才必须执行此操作。要存储在WWDG_CR寄存器中的值必须在0xFF和0xC0之间。7 k1 u" |4 H0 e7 z( }4 Y1 c
6 a% n' p+ R& j( `
框图
5 O- l. \9 w* I% a1 i5 @! _: a0 k1 e
20200524174123541.png

. w. j, s8 j6 ]* t  `; j
$ v9 z) H  K/ T1 W/ N启用看门狗% |/ c( x% c5 @  n* l$ M
当FLASH选项字节WWDG_SW选择“软件窗口看门狗”时,看门狗在复位后始终被禁用。通过将WWDG_CR寄存器中的WDGA位置1可以启用它,然后只能通过复位将其禁用。) A7 T. J; X- W: M
当FLASH选项字节WWDG_SW选择“硬件窗口监视程序”时,在复位后始终启用监视程序,因此不能将其禁用。 9 X, l* D4 M' n
递减计数器用法
% C2 g& C) c6 S, a该计数器可以自由运行,即使禁用了看门狗也可以递减计数。 当看门狗使能时,必须将T6bit置1以防止立即产生复位(即T[6:0]大于0x3F);
- a% o2 R) l6 T4 T
! [4 X# B0 {% R- a为防止复位,当计数器的值小于窗口寄存器的值且大于0x3F时,必须重新装入递减计数器。 下图描述了过程:
1 k8 q% U( q9 X3 |
0 {8 i) Z2 u/ f- E
20200524180957776.png

4 U. R7 P2 _5 d8 ?" m, O4 k- e( ~! s: E' Z/ f& K; k6 a: ]% q1 S! y' k3 a
提前唤醒中断(EWI)
0 J: J3 N; }8 x" E
, Y, [5 v* R, c  p) w; m$ T/ l/ S9 Q 通过将WWDG_CFR寄存器中的EWI位置1,可以使能EWI中断。当递减计数器达到值0x40时,将在重置芯片之前生成EWI中断,相应的中断服务程序(ISR)应该重新装入WWDG计数器以避免WWDG复位,然后触发所需的操作。通过将WWDG_SR寄存器的EWIF位写为0,可以清除EWI中断。当无法处理EWI中断时,例如由于较高优先级任务中的系统锁定,最终会产生WWDG重置。
9 \& F2 w2 h& Q' |! g1 z; p" Z7 \! }' w9 G- g1 u7 y
计算超时时间: c! L" D& _! [6 L

$ Q2 F4 J0 \) A5 F5 J2 [- V4 H
20200524184059993.png

3 y% _$ U/ o: e& V0 B& _+ a% ~" c2 M4 y8 d
如:当APB=48MHz,WDGTB[1:0]=3,T[5:0]=63时;# J1 p0 x  L# d1 y* ^9 d1 o( Q4 h

% }3 U& q) }& p  P
20200524184304815.png
8 j2 m/ s$ v. d" ~0 z0 D- {

& @1 e, z2 }4 D. L3 k' d) ?3 O7 x( i6 R寄存器% p, g0 _( V, i" ?* {- [
寄存器可通过半字(16位)或字(32位)进行访问。
& h+ }8 }( M! {4 Y6 s
9 U' ]) I% z. {+ E 控制寄存器(WWDG_CR)
8 e6 |& S$ j0 C5 c- v# \9 N  T

; c" t1 Q% k) |! \/ n' J" s偏移地址:0x000
$ ?7 i2 W# m) i0 d- x0 g& w0 w; L# _0 s, z5 `$ n
复位值:0x0000 007F( x$ ?9 ^( u6 s( {% f) T
' y" b! R; {7 E  J/ H& ~: ]; G. u
BIT7:WDGA(r/s),启用看门狗。由软件置1,只能通过复位让硬件清0。0:禁用看门狗、1:启用看门狗
, h; p5 d% ~) C* O& t# S$ _/ t. Q/ J7 d. w9 [' f
BIT 6:0:T[6:0](r/w),7位计数器(msb to lsb),当值从0x40减到0x3F时产生复位(T6bit被清除)- R: o0 h: \; x7 R# ?  z
! \+ W6 H$ P* Q1 Z7 `; T, H' O
配置寄存器(WWDG_CFG)
  H: Z1 q  b; z* X7 e5 G$ z+ ~5 @) v
偏移地址:0x004
" e1 V" P6 G) H  g
2 s$ [* r0 A0 Z" k  Z3 _复位值:0x0000 007F
2 _0 K" ~, h4 G. J6 G, C+ J# I: R/ w1 T, `1 ^6 U
bit 13:11 WDGTB[2:0] (r/w),时基2 r' R  G. b3 V3 T. G
& d" X! y1 ?  r4 q, j( p& A* Y
000: CK计数器时钟 (PCLK 分频4096) 除以1
6 P( k" ^4 g3 d6 c001: CK计数器时钟 (PCLK 分频4096) 除以2
4 N! a( W7 Y0 ?! Y. U8 t! ]010: CK计数器时钟 (PCLK 分频4096) 除以 4
1 O/ ^; U% e7 C6 b0 C011: CK计数器时钟 (PCLK 分频4096) 除以8
+ M' Q; c3 r" R: c! A$ D2 ~5 x; H100: CK计数器时钟 (PCLK 分频4096) 除以16
# V7 K* b# `" Z: p# a101: CK计数器时钟 (PCLK 分频4096) 除以32/ V/ u8 g+ g: v3 \
110: CCK计数器时钟 (PCLK 分频4096) 除以64
% ~& |- S5 }5 e5 ?! t  u, \111: CCK计数器时钟 (PCLK 分频4096) 除以128
+ g  ]  I# v7 R9 s+ B" L% ?- X+ [8 L: O. w" t" P2 F- W8 t. v
bit9 EWI (r/s), 提前唤醒中断位,置1时,只要计数器值到0x40就会发生中断。该中断仅在硬件复位后清楚。
; {+ ?# Q: ~* K/ ^  E3 w3 R3 ~
$ q9 p1 N  ]' h3 c' S+ s4 I( ^bit6:0 W[6:0](r/w),7位窗口值,用来与递减计数器比较的窗口值。
* b% t' P: m; R* V9 U3 ^+ `$ i( s  l& g% ]. A. Y# Z
状态寄存器(WWDG_SR)4 H3 V* h* f- g
& y9 p( L6 A" ]3 V) f, k) h
偏移值:0x008
7 j+ E" a" X- L7 n- O4 u, l) O6 k' |5 E$ ~- R( ~
复位值:0x0000 0000
; q' S2 O4 y2 w4 m1 \: x- w" t3 ^
- r+ C2 k, ]2 w4 ~* Y. ?. K) vbit0 EWIF(rc_w0) 提前唤醒中断标志,当计数器达到值0x40时,此位由硬件置1。 必须通过软件将其写入“ 0”来清除它。 写“ 1”无效。 如果未启用中断,则该位置1。  Q9 Q" d2 Q& l
6 G( w9 P- F$ \" T5 }0 q0 h
实验示例
1 f5 j* G1 f$ R/ e$ U9 {1、开启调试接口、HSE
* l% {2 y9 }4 c& I9 H, h" W  p" i
20200702225341466.png

4 f5 s1 V7 J8 v$ F4 e* c" I) ^
! ], }: E/ `/ t3 e7 _: D5 Z
20200702225405256.png
3 J4 S2 X& S3 C7 Q* R

3 X5 z$ h% l) P9 Q- Y" M7 y2、 PA0设置为GPIO_Input,在NVIC中使能看门狗中断3 h6 S) K  H; T: h

1 q8 ~0 t, T* p" i
20200702225814679.png
& Z& M( L& t4 B6 X

5 [0 u& y8 Z) _* J0 o0 N0 C3、使能USART1,使用异步模式,波特率115200,8,none,1( X9 i& E* H$ _7 N1 E/ ?( u8 r
; r, r/ }# ?$ {7 e8 R7 P: K
20200702230037736.png

7 d  ^& B6 Y- ^4 M' Z. t
( F' y' Y# `" z( c% a# Z! Y0 e
20200702230050880.png

% A0 S; }3 `! D- w! G
! u- R$ Z% L8 K% i8 r4、激活WWDG,设置分频系数128,窗口值(64~127)=64,计数值=127
8 u" D  s8 M# l1 h7 ?/ R# |. L
8 K9 g3 g0 D) ^5 v+ S7 c4 o
20200702225845997.png
6 @3 v7 r+ p/ S. M
9 k% H* m) T7 B
5、设置时钟树,HCLK=64MHz、PCLK=32MHz. C; e- K- Q8 q: T3 r; C+ k
5 P1 G/ R- z2 r* }  z6 L/ c7 z
20200702230304582.png

7 Y+ I/ \1 [: a
/ ?' j8 l) A% L0 D. S2 r6、利用上面的公式,计算当计数值T[6:0]到0x40的时间,引发EWI中断进入喂狗的时间
3 M' i0 h+ k: `. I7 P# h8 \# |4 e9 n$ \/ M& V! {- X. N' H$ \
   =1048.576ms
2 L; R: n; G( w' U1 i: r7 b; ~  C8 u( x! N6 y: T
即每1048ms喂一次狗。9 C0 f# l0 `' M

7 y  i; @, t7 t3 g( Z8 ^, S7、设置工程文件属性,生成代码。9 j" ]. `4 C+ j

- \- o/ e+ a. J6 ]2 J4 P: q, O. r
20200702231252969.png
8 w9 V2 {+ l: f; t( z' o- G
* `* Q  |. m; E' c0 h* S, r
) C) p7 V: ?& n/ [
20200702231302949.png
! W+ q7 t' a2 l

: f/ L1 {3 @' F( C. j
20200702231406699.png

/ `  G( |. y' H7 {9 I7 i& }
% X2 }; z0 D4 y, i% ]8 D% Q% s0 v( k
代码 9 S; i0 b1 M4 b/ \! y
1、在USART.c文件中加入串口打印代码
# Q' u. T+ W8 T' ^1 x
  1. /* USER CODE BEGIN 0 */
    / y& q/ ]* Q4 t# h
  2. #include <stdio.h>! c; b, ?! C8 M, X# z7 T  J" ]' L
  3. #ifdef __GNUC__
    * o' q0 z4 N; j1 R% ~0 {( [
  4.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    $ X0 k* b" I1 ~7 W
  5.      set to 'Yes') calls __io_putchar() */
    9 R1 {/ j3 v- @9 o. F
  6.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    0 n, ]3 ?0 C5 U$ O7 I
  7. #else( U$ {% L- C: Y0 X( j" r6 u6 B  q
  8.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    4 G* T' N1 s& @1 Y- y
  9. #endif /* __GNUC__ */$ d& }$ U; e, O  U1 b7 Y
  10. /**/ u) h- M. I' F% Z6 e7 ]3 V% k
  11.   * @brief  Retargets the C library printf function to the USART.
    ! v: Z6 Q9 z# ~1 K0 j" e( ]
  12.   * @param  None3 B4 L1 K& k- ^$ m4 o( F
  13.   * @retval None. m, W: X4 p7 T. @
  14.   */
    . a: r; Z( J( y% J' S
  15. PUTCHAR_PROTOTYPE$ K; b" V4 c& |: M0 K, a0 P
  16. {
    / N0 w  t' X' X  U: p9 J
  17.   /* Place your implementation of fputc here */
    $ x" C4 {( z) \' X
  18.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */0 E3 O' U: S8 _
  19.   HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);, U; m+ W. l9 p. o0 r
  20. 5 Y$ T# ~* [' z% w" T# e, D; Y
  21.   return ch;
    ! j' w& z2 _3 T8 M$ A
  22. }
    , [/ }0 i' X+ {* O% b
  23. /* USER CODE END 0 */
复制代码

+ L6 ]7 i6 e1 J% n' H0 R9 }- X2、在main.c文件中加入开机打印代码,6 `7 j  m0 a5 {

$ _1 d$ A: a, n; P+ m6 u
  1. #include <stdio.h>
    & _9 S* ]/ M0 I- \. X
  2.   MX_GPIO_Init();: P  z6 f. k8 ^" d
  3.   MX_USART1_UART_Init();
    . t$ |% i1 V, H  v4 z) K1 H
  4.   MX_WWDG_Init();
    6 `& k" m, m! i$ E# Z* m
  5.   /* USER CODE BEGIN 2 */2 n9 K5 N- L3 V4 r* G( p* k
  6.   printf("...RESTARTing...");    //开机打印2 _& ~% l9 k5 A7 U7 R& D
  7.   /* USER CODE END 2 */
复制代码

8 j/ P  Y7 `7 |7 w加入EWI中断代码
' n# R6 O1 Y0 P
  S# Q+ H  L+ t
  1. /* USER CODE BEGIN 4 */2 K2 Y! H) f+ {1 n
  2. void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)  i/ g& ^. I& m) x5 \. |5 Q
  3. {
    1 O# P( X4 _" S7 @
  4.   /* Prevent unused argument(s) compilation warning */2 |* q' [4 _. n
  5.   UNUSED(hwwdg);) v8 j+ ?* X" A
  6.   if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))         //检测PA0是否按下,按下就喂狗( B9 X: B. V+ p0 M7 G, h$ U
  7.   {
    6 Q& I6 F: Y: \( ^) E8 B9 U: }- f
  8.     HAL_WWDG_Refresh(hwwdg);
    " @! t1 o2 ?) K2 @  P  a: i8 n) V% O
  9.     printf("Refresh,OK");                  P, i) V& E: f$ L
  10.   }$ i# C  k& _6 g$ }; K8 @9 Z7 ~/ O
  11.     else
    . c" S8 w# {8 [1 Y( D; R
  12.   {  L2 {3 A+ [! U  @2 ?5 b8 _
  13.     printf("Fail");
    - n# Z6 |4 A4 l5 S9 }
  14.   }- A9 h0 @3 I, ]6 a+ ^. c
  15.         __HAL_WWDG_CLEAR_FLAG(hwwdg,0);               //清除中断标志
    # x6 O% D  ^" T, Z6 G  |1 `
  16. }
    ' w' l+ q/ Y4 ?- n
  17. /* USER CODE END 4 */
复制代码

( L6 b) d2 r% M0 D6 i8 b$ v3 C1 d8 W3、编译,烧录之后就看到效果8 b, B+ o4 m5 [
- [! J+ H/ ^2 p! G/ h$ i
20200702232811689.png
( i% r8 p" F  Q- E, \. z3 I6 i: P
3 z5 g7 O3 I/ s$ W. E/ Q( `! Z
; _; H; y3 |' E& o! o' G# j

3 G7 W! f/ z2 q5 O; b. G; f  @
赞 收藏 评论0 发布时间:2021-12-9 11:07

举报

0个回答

所属标签

相似技术帖

官网相关资源

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