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

STM32G0学习手册——WWDG运用

[复制链接]
STMCU小助手 发布时间:2022-10-28 18:39
概述
. G, P/ v0 s. E& v系统窗口看门狗(WWDG)用于检测软件故障的发生,通常由外部干扰或无法预料的逻辑条件引起,导致应用程序放弃其正常顺序。 看门狗电路会在编程的时间段到期时生成MCU复位,除非程序在T6位清零之前刷新倒数计数器的内容。如果在递减计数器达到窗口寄存器值之前刷新递减计数器值,也会产生MCU复位。这意味着必须在有限的窗口中刷新计数器。WWDG时钟是从APB时钟预分频的,并具有可配置的时间窗口,WWDG最适合要求看门狗在准确的时序窗口内做出反应的应用。% a; K8 [- ?* w0 Y+ Z9 `+ d

# C2 P, ]2 `: g  i& y主要特性 $ q8 q: [9 h6 [# f
激活窗口看门狗后,如满足如下条件则重置芯片:% \- S. R: B7 o7 R
当递减计数器的值小于0x40时
6 t" ?* G* N  H6 d1 j4 L# G: s9 @- I窗口值外重新加载递减计数器( a9 }+ J1 o% k0 V* P
如果启动了窗口看门狗并允许中断,当递减计数器等于0x40时产生提前唤醒中断(EWI),可以被用于重装栽计数器以避免WWDG复位。
$ I6 j+ G' }9 X" w1 a0 m
  H3 ?  E% k, Y9 A用法
/ y8 |* p4 g9 A7 S如果看门狗被激活(WWDG_CR寄存器中的WDGA位置1),并且当7位递减计数器(T [6:0]位)从0x40递减到0x3F(T6被清除)时,它启动重置。 如果软件在计数器大于窗口寄存器中存储的值时重新加载计数器,则会产生复位。
' h, E7 ]5 _. k5 P6 m- y3 e# @: D# M6 }% G) w2 M
在正常操作期间,应用程序必须定期在WWDG_CR寄存器中写入数据,以防止MCU复位。 仅当计数器值小于窗口寄存器值且大于0x3F时,才必须执行此操作。要存储在WWDG_CR寄存器中的值必须在0xFF和0xC0之间。
% B: K3 R  W2 s) s5 f" c% T! R7 ^" p7 D* D
框图& ^9 E% H1 I" ?
3 e2 Z# g, l5 y4 e8 P9 X' u
20200524174123541.png " C4 @; F4 r+ N) s% ?, J" b+ R

( Y% K2 J1 L. V* a0 x. S启用看门狗
: t' ^4 q! |( s  M0 @0 t当FLASH选项字节WWDG_SW选择“软件窗口看门狗”时,看门狗在复位后始终被禁用。通过将WWDG_CR寄存器中的WDGA位置1可以启用它,然后只能通过复位将其禁用。
# h$ V- x2 A. k$ d6 b( Y当FLASH选项字节WWDG_SW选择“硬件窗口监视程序”时,在复位后始终启用监视程序,因此不能将其禁用。
$ ~6 G, O* K; l5 ?+ Z' `
( }; M2 c/ h, f; X9 K1 n; o) u% b* r递减计数器用法
: v9 @# q" u1 Z8 o  _该计数器可以自由运行,即使禁用了看门狗也可以递减计数。 当看门狗使能时,必须将T6bit置1以防止立即产生复位(即T[6:0]大于0x3F);
) [# n8 {7 Y( ^$ J! `2 D
* h; @. a- u9 I+ k' _为防止复位,当计数器的值小于窗口寄存器的值且大于0x3F时,必须重新装入递减计数器。 下图描述了过程:! N! p: S) y. k9 F6 X* z9 j$ O! p

1 ?# C& R$ _8 R+ M+ @5 @8 U 20200524180957776.png - @* Y9 S9 ]5 ~

) h0 x! G0 Z% v: [$ J) Q 提前唤醒中断(EWI)
+ }7 _1 z  S' u7 _5 `! [
' ]$ h) P4 t8 K4 N9 \$ h6 H 通过将WWDG_CFR寄存器中的EWI位置1,可以使能EWI中断。当递减计数器达到值0x40时,将在重置芯片之前生成EWI中断,相应的中断服务程序(ISR)应该重新装入WWDG计数器以避免WWDG复位,然后触发所需的操作。通过将WWDG_SR寄存器的EWIF位写为0,可以清除EWI中断。当无法处理EWI中断时,例如由于较高优先级任务中的系统锁定,最终会产生WWDG重置。* X" H; V% Q2 L6 N  W
  [0 Y0 S+ j* a) g2 v$ ~, c
计算超时时间
% K) A" m! T: {" X% H* S1 [
$ x; o6 [# |: O+ E+ i+ u 20200524184059993.png 1 P" g" H, ]1 F' S4 b! L- O; l5 C
8 V7 c; \" s6 A
如:当APB=48MHz,WDGTB[1:0]=3,T[5:0]=63时;) g$ F1 s) ], {. w4 l: G, b# q, {
  x( f9 N5 g# j/ B/ Y$ K; i
20200524184304815.png % [# m+ [( X( f! _

% c. P  T! {8 _- D寄存器
) J5 P% f3 g8 q$ z7 ^寄存器可通过半字(16位)或字(32位)进行访问。
- U, \, j$ j0 j% Q
1 a; E8 A; K+ `3 E) g7 }3 F 控制寄存器(WWDG_CR)
6 o* V6 `7 a6 z4 X5 J8 @$ v! T. M( z$ e/ {  c
偏移地址:0x000
: F$ s* z1 ?. q3 b+ s: X3 ]5 J( p; l9 h: t8 C
复位值:0x0000 007F: H. u0 r% C) B, p5 K! K( y! |

2 L. ]6 [* ?0 Z5 P* I; p# tBIT7:WDGA(r/s),启用看门狗。由软件置1,只能通过复位让硬件清0。0:禁用看门狗、1:启用看门狗! x4 D9 m3 I4 ]% M2 |' S' F  C- `
+ G  Q. ?" _4 N8 [, Q: S. R6 X
BIT 6:0:T[6:0](r/w),7位计数器(msb to lsb),当值从0x40减到0x3F时产生复位(T6bit被清除)
$ u( ]6 J# J/ u) t; i: h4 i$ K& f7 z) z9 _, v
配置寄存器(WWDG_CFG)/ _% ?9 B! p& b; f5 f
/ ]  t& e# y6 t7 Q% O# ^2 U
偏移地址:0x004
( T, r% @' Q! K5 m- j- A8 P7 j4 E' `& [3 R, Y
复位值:0x0000 007F
4 r/ O4 w! L) M0 h5 d7 O* H9 ~9 x/ Z* L( T0 g' U9 a/ o7 v8 n/ v
bit 13:11 WDGTB[2:0] (r/w),时基4 D' D' U/ Q" X. }: B- r

0 F- C' {. K" y' O' d) i8 E& e1 x: g000: CK计数器时钟 (PCLK 分频4096) 除以10 _" N" [) [) Q* B3 ^/ N" n
001: CK计数器时钟 (PCLK 分频4096) 除以21 J. r0 E; p2 j. D- j
010: CK计数器时钟 (PCLK 分频4096) 除以 4
. w5 W3 ^8 s; D" b011: CK计数器时钟 (PCLK 分频4096) 除以8+ z9 W! d( _: g3 q" V
100: CK计数器时钟 (PCLK 分频4096) 除以16# ]' q0 W+ G+ I: E" {. A
101: CK计数器时钟 (PCLK 分频4096) 除以32
1 ], `; ~. E0 J$ }  P- ^110: CCK计数器时钟 (PCLK 分频4096) 除以64$ a/ x( ]9 H& r% g/ Y
111: CCK计数器时钟 (PCLK 分频4096) 除以128
; k; @3 e! @5 X9 C& ], N/ v
* ?' |1 f5 Q+ d* @: q! n4 |bit9 EWI (r/s), 提前唤醒中断位,置1时,只要计数器值到0x40就会发生中断。该中断仅在硬件复位后清楚。
' O% y* `0 t4 `, Z
: i6 f$ }8 A2 |% A2 _bit6:0 W[6:0](r/w),7位窗口值,用来与递减计数器比较的窗口值。
3 {2 }- T9 k+ {9 W) \5 O9 x- y( B$ {* ]
状态寄存器(WWDG_SR)+ X/ a$ g$ L1 {  t' d
* k& h7 [2 Q  q) [) z
偏移值:0x008* M8 B0 V) y9 [* c( i3 T

7 A! K& y6 M$ L! a" C复位值:0x0000 0000/ m* G8 o/ u2 K% T/ m% j* B" t# [& M

# O" {1 B- q; {: ~5 c9 D( z/ Bbit0 EWIF(rc_w0) 提前唤醒中断标志,当计数器达到值0x40时,此位由硬件置1。 必须通过软件将其写入“ 0”来清除它。 写“ 1”无效。 如果未启用中断,则该位置1。# S$ I: G+ H3 F

2 G5 ^1 w3 ~+ W, [# H6 }" D实验示例  b0 o! S, {" ~2 D, \' ^
1、开启调试接口、HSE# q/ u! s+ t* d; \. ?  G0 _* b. V
1 T4 p, T8 A; p9 |* f
20200702225341466.png
% B& o/ t) S2 H0 _2 O$ m" t, _% l, S! l: X4 x8 G' d
20200702225405256.png 5 O+ j2 P4 k# r  P

1 B' [( P+ P# ~: f7 d+ m2、 PA0设置为GPIO_Input,在NVIC中使能看门狗中断) c, z) S8 f4 _( T& |% @
3 X3 \- u2 q. L" C2 E6 q. j* o
20200702225814679.png % O8 g( D: D8 o* \# e$ o% [9 B

3 F( E  [  o+ [3 h) o3、使能USART1,使用异步模式,波特率115200,8,none,1: A/ n, I  {6 g6 W6 s9 ]
+ t* N: t7 q; G# S4 l7 X
20200702230037736.png 9 r! W5 t  H- C0 d1 u8 X
* n: B% f* v/ Z; [$ t( S9 Q7 u
20200702230050880.png 4 X! c. p- N! a; ?7 [9 s& {
/ j8 `/ U7 x& z6 o
4、激活WWDG,设置分频系数128,窗口值(64~127)=64,计数值=127
- C: U( v+ m# L% D- r  ]3 [" C. S4 T* h( m( ^. Y! ^/ e8 ^
20200702225845997.png % G, q+ Z( g% ]2 a+ c6 q5 @+ F

) Z0 {2 u6 c' Q9 b  ], V$ i5、设置时钟树,HCLK=64MHz、PCLK=32MHz& d% W, W3 O/ X1 a# |- x

) k- a  ]) ]! U& ~ 20200702230304582.png / j( b  F* t& \  l
4 m+ I+ h/ _3 n
6、利用上面的公式,计算当计数值T[6:0]到0x40的时间,引发EWI中断进入喂狗的时间
  b2 I$ M0 S; l9 }, P+ l2 E# M, V0 B# S2 i1 G
   =1048.576ms  |$ w! K4 R2 d' }9 w/ ?% U
4 v& X% q% l5 a
即每1048ms喂一次狗。6 j/ U6 ?9 Q1 m, Y" R
& ~& j1 }, p- j' d0 n% W, f
7、设置工程文件属性,生成代码。+ t! E5 N2 d  C

; ]. {# o6 j+ l7 }* N! o% x 20200702231252969.png
# ^. m; l* k- `- x- b$ |) q/ v7 G! ^# V7 n5 o) M& @& y: v- O* `' q
20200702231302949.png
8 I" T8 e" q4 S2 a) _
  n6 ~/ M( {3 E  L 20200702231406699.png 3 x5 L$ s' E% K: R

9 |9 b$ D+ o' @: [$ \) ?代码   j/ @7 {/ ~8 t( Z  F
1、在USART.c文件中加入串口打印代码
8 `* ~* s. g1 ]3 G9 F7 `4 ~5 O4 q0 s$ m' C$ T6 P$ I- x
  1. /* USER CODE BEGIN 0 */
    - [2 W6 s- g: f6 t% R8 [
  2. #include <stdio.h>
    " k" T* N8 j9 f7 M3 }  d
  3. #ifdef __GNUC__9 p5 Z# g  q* v- D
  4.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    . L* b4 _5 J- M8 L) Z- d, S
  5.      set to 'Yes') calls __io_putchar() */$ U3 w, o' T4 i" R' V
  6.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)6 x6 Y+ W$ }3 o& h( o7 r3 V9 k( u& z
  7. #else3 P7 P5 M! f8 }, n5 J9 b3 ~
  8.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    ) B2 B7 U  n* d6 ?( I/ h6 A+ _$ x
  9. #endif /* __GNUC__ */
    : j9 @+ ]4 t5 `/ ?0 z2 F
  10. /**
    0 H9 L- F% c" B9 `9 y
  11.   * @brief  Retargets the C library printf function to the USART.
    ) _$ f3 ^9 G- T+ K
  12.   * @param  None5 V, b+ C' g: u+ I" t6 L# d; }3 Q6 I
  13.   * @retval None
    $ V" u8 w4 R( N; E% J1 y$ ]
  14.   */
    7 N( j8 u% Z% U) N+ j% _5 P" E
  15. PUTCHAR_PROTOTYPE! f$ Y  g2 |; `" x' E7 _. z
  16. {  _  C9 B+ W# t7 F6 D# J! y; T
  17.   /* Place your implementation of fputc here */0 ~2 A9 |1 I# c1 V9 {* `1 o2 d# W
  18.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    " M( v5 _  F* q2 f) L* }% l
  19.   HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);* F5 i$ S( N  u& O5 s7 x/ f- t
  20. 1 @. H/ m  W: A* M, `* \
  21.   return ch;
    * w  p4 ~4 }7 @. E0 n1 ?
  22. }
    . D" P2 |4 }8 U5 Z0 x+ h0 t( M
  23. /* USER CODE END 0 */
复制代码

( l3 Z$ @, X2 l9 B  F3 d6 D2、在main.c文件中加入开机打印代码,8 N  q0 \5 u9 u5 l' H6 P
8 r9 E1 x( \' v* S8 ~6 y2 O
  1. #include <stdio.h>
    ; V, M  V' y9 l) n" N/ e4 F/ l% P
  2.   MX_GPIO_Init();
    6 w' G' y9 ]9 Z+ @; B/ K
  3.   MX_USART1_UART_Init();
    : D$ H/ M# K# u& t0 H* i# ]
  4.   MX_WWDG_Init();
    6 ^# M" w, @/ f) c
  5.   /* USER CODE BEGIN 2 */
    2 a0 J  |% k1 x" C7 i# m3 @( U
  6.   printf("...RESTARTing...");    //开机打印5 x4 J6 g, r* L9 A! c7 Y- p; ]
  7.   /* USER CODE END 2 */
复制代码

! b8 Q  \6 D0 B% a' [加入EWI中断代码
/ a8 h9 Q7 O5 K+ V3 S+ N+ A9 a0 B& \+ y, a8 m3 s
  1. /* USER CODE BEGIN 4 */
    . Y5 ?7 m. Q# Q, M
  2. void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
    ) [6 y4 A( r# G1 `5 z& ~
  3. {' p: W% W$ \+ f' U1 D  I
  4.   /* Prevent unused argument(s) compilation warning */
    + |+ E$ ~8 n, f% j. W$ _' H9 J
  5.   UNUSED(hwwdg);$ [! h" J! g  r7 R- y2 h
  6.   if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))         //检测PA0是否按下,按下就喂狗
    $ w) q1 G3 a& k* M! K1 `. h% F
  7.   {1 E) Q, r9 l3 W, G) A- F
  8.     HAL_WWDG_Refresh(hwwdg); 1 w  O- L- _& n: `
  9.     printf("Refresh,OK");               
    0 V* \7 ~2 E- P# K. c
  10.   }. N: P) U/ r& ^6 ^( i) ~3 q( ]
  11.     else) R. _  c, Q9 e% Q8 N9 O) j
  12.   {
    . _% g/ M; l  T7 t
  13.     printf("Fail");. f; @3 m3 w$ X% v( O& l
  14.   }
    9 O8 w$ A6 e7 W! t$ w$ w+ m
  15.         __HAL_WWDG_CLEAR_FLAG(hwwdg,0);               //清除中断标志9 O: q# Y- k+ Y* q7 @- c  O3 ?& R% O
  16. }$ l1 o! i' \* h/ h: u7 a3 u! M$ z& V
  17. /* USER CODE END 4 */
复制代码

2 y* P3 w7 L2 s+ f0 G+ A3、编译,烧录之后就看到效果
: Z0 [* v6 f- ?- i2 S6 v
5 l6 h8 \/ O) R6 C% r/ d 20200702232811689.png " w# c: \4 T' T( \

8 c4 v3 A( @$ x7 T: L+ r9 t————————————————, K5 G* l  j7 T! j, j
版权声明:SCCELE  e7 E) k% o4 ^) E
$ q3 m: K4 E6 d8 R+ Y

9 a' _  L2 r2 `+ K# P
赞 收藏 评论0 发布时间:2022-10-28 18:39

举报

0个回答

所属标签

相似技术帖

官网相关资源

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