×
嵌入式 > 技术百科 > 详情

STM8S_008_WDG独立看门狗和窗口看门狗

发布时间:2020-06-19 发布时间:
|

Ⅰ、写在前面


STM8S看门狗WDG分为两类:

IWDG:Independent WatchDog独立看门狗

WWDG:Window WatchDog窗口看门狗

 

独立看门狗模块可以用于解决处理器因为硬件或软件的故障所发生的错误。它由一个内部的128kHz的LSI阻容振荡器作为时钟源驱动,因此即使是主时钟失效时它仍然照常工作。

 

窗口看门狗用于监测由于外部干扰或不可预知的逻辑条件所产生的软件错误,这样的软件错误通常会导致应用程序不按照预期的方式运行。

 

大概意思主要是:IWDG主要防止硬件问题引起的复位,WWDG主要防止软件问题引起的复位.

 

作者:strongerHuang

版权所有,未经允许,禁止用于其它商业用途!!!

 

Ⅱ、看门狗基础知识

1.看门狗结构图

STM8S的独立看门狗IWDG比窗口看门狗WWDG结构看起来要简单一点,其实寄存器都只有那么两三个,软件配置起来也比较简单。不管是独立还是窗口看门狗,自己看结构图基本就能理解到它们。具体请看下面结构图进行对比。

独立看门狗IWDG结构图:


当向下计数器“8-bit down-counter”等于0时,就会产生看门狗复位“WDG reset”。因此,就需要在计数器等于0之前通过重载寄存器“IWDG_RLR”更新计数器的值。

 


窗口看门狗WWDG结构图:


窗口看门狗有两地方会引起复位:

1.当7位(T[6:0])递减计数器从0x40翻转到0x3F(T6位清零)时。这种和上面IWDG类似,递减到“0”就会复位。

2.当更新的计数值大于窗口值(T6:0 > W6:0)时。

 

这两种复位的情况如下图:


 

2.IWDG独立看门狗功能

当在键寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就被启动了,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号(WDG RESET)。

 

如果在IWDG_HW选择字节中使能了硬件看门狗的功能,在芯片上电时看门狗的功能被自动开启,如果软件不能及时操作键寄存器,则在计数器达到0x00时产生复位。

 

看门狗复位的超时值是由你的配置(分频值和计数值)决定的,大概如下(默认LSI = 128 kHz 会随温度变化有所偏差):


3.WWDG独立看门狗功能

● 可编程的自由运行递减计数器

● 有条件的复位

─ 如果开启了看门狗,当递减计数器的数值小于 0x40 时产生复位

─ 如果开启了看门狗,当在指定的时间窗口之外重加载递减计数器的数值时产生复位

● 硬件或软件启动看门狗(由选择字节指定)

● 可在HALT指令时产生复位(由选择字节配置)

 

● 开启看门狗:

如果(通过选择字节)选择了软件看门狗,在系统复位后看门狗处于关闭状态。设置WDGCR寄存器中的WDGA位将开启看门狗,随后在下次复位之前将不能关闭看门狗。

如果(通过选择字节)选择了硬件看门狗,看门狗将始终开启,而WDGA位将不起作用。

 

● 控制递减计数器:

递减计数器是自由运行计数器:即使未开启看门狗,它依然不断地递减计数。当开启看门狗时,必须设置T6位以避免立刻产生复位。

T[5:0]位中包含了看门狗产生复位前允许的时间延迟;因为写入WDGCR寄存器时,预分频器的状态是不可知的,所以这个时间延迟介于一个最小和最大数值之间。

 

窗口寄存器(WDGWR)的数值是指定窗口的高限:为防止复位,必须在递减计数器的数值小于窗口寄存器的数值并大于0x3F时刷新递减计数器。

提示: T6位可以用于产生一个软件复位(即设置WDGA位同时清除T6位

 

● 在停止时产生看门狗复位

如果开启了看门狗,并且选择了停止时产生看门狗复位的选项,则执行HALT指令将产生复位。

 

Ⅲ、 软件工程源代码

1、关于工程

本文提供两个版本的工程代码:

STM8S-A08_IWDG独立看门狗

STM8S-A08_WWDG窗口看门狗

 

本文提供的工程代码是基于前面软件工程“STM8S-A04_UART基本收发数据”增加WDG看门狗修改而来。初学的朋友可以参看我前面对应的基础文章,那些文章讲的比较详细。

 

2.IWDG独立看门狗代码分析

A.IWDG_Initializes初始化

void IWDG_Initializes(void)

{

  IWDG_Enable();

  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

  IWDG_SetPrescaler(IWDG_Prescaler_256);

  IWDG_SetReload(250);

  IWDG_ReloadCounter();

}

预分频值为IWDG_Prescaler_256,参数为枚举类型:

typedef enum

{

  IWDG_Prescaler_4   = (uint8_t)0x00,

  IWDG_Prescaler_8   = (uint8_t)0x01,

  IWDG_Prescaler_16  = (uint8_t)0x02,

  IWDG_Prescaler_32  = (uint8_t)0x03,

  IWDG_Prescaler_64  = (uint8_t)0x04,

  IWDG_Prescaler_128 = (uint8_t)0x05,

  IWDG_Prescaler_256 = (uint8_t)0x06

} IWDG_Prescaler_TypeDef;

 

重装计数值为8位寄存器,最大255,我们设置为250.

 

我在初始化看门狗时,将复位超时值设置为1000ms,具体计算为如下:

128K/2 = 64K (输入时钟)

64K / 256 = 250 (分频后时钟)

250 / 250 = 1 (重载值为250)


B.功能测试代码

void main(void)

{

  System_Initializes();

  UART1_Printf((uint8_t*)"Start...");

 

  while(1)

  {

    LED_REVERSE;

    TIMDelay_Nms(990);

 

    IWDG_ReloadCounter();

  }

}

 

第一:如果复位,会打印“Start...";

第二:我们配置复位超时值为1000ms,理论小于1000ms内喂狗都不会复位,由于LSI有偏差,我们设定在990ms喂狗一次。

第三:修改延时值为1010,则会发现系统复位(打印“Start...")。

 

3.WWDG窗口看门狗代码分析

A.WWDG_Initializes初始化

#define WWDG_WINDOW_VALUE  0x7F  //窗口值

#define WWDG_COUNTER_INIT  0x7F  //计数值

void WWDG_Initializes(void)

{

  WWDG_Init(WWDG_COUNTER_INIT, WWDG_WINDOW_VALUE);

}

 

为了方便测试,我们这里将窗口值和计数值定义为宏,范围:0x40 - 0x7F.

 

B.功能测试代码

void main(void)

{

  System_Initializes();

  UART1_Printf((uint8_t*)"Start...");

 

  WWDG_Initializes();

 

  while(1)

  {

    LED_REVERSE;

    TIMDelay_Nms(49);

 

    WWDG_SetCounter(WWDG_COUNTER_INIT);

  }

}


第一:同理,如果复位,会打印“Start...";

第二:我们配置复位超时值为49.152ms,如果这个延时大于49(设定为50及以上),就会复位(打印“Start...")。

第三:如果我们修改延时值(假如为TIMDelay_Nms(10);),修改窗口值为#define WWDG_WINDOW_VALUE    0x4F。则不在喂狗窗口范围内,会发现系统复位(打印“Start...")。

 

提醒大家:多测试验证才能更容易理解和记住功能的要点。

 




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil5(MDK5)在调试(debug)过程中遇到的问题