打印

【连载】STM8L051F3_16_WWDG应用

[复制链接]
1121|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
caijie001|  楼主 | 2018-5-24 18:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文介绍STM8L051F3的WWDG相关知识。内容分为以下几部分:
  • WWDG简介
  • WWDG应用
1、WWDG简介WWDG(Window watchdog):窗口看门狗。窗口看门狗用于检测由于外部干扰或者未知的逻辑错误而导致软件错误的发生。如果不在递减计数器T6位被清零前刷新计数器就会产生一个复位,在计数器值没有小于串口值前进行刷新也会导致复位产生,这意味着计数器必须在窗口值内进行刷新。WWDG的主要特点如下:
  • 可编程的独立递减计数器
  • 复位条件:
    • 当计数器值小于0x40
    • 在设定的窗口值之外对计数器进行刷新
  • 可硬件/软件激活WWDG
  • 在HALT指令下可选择复位
在WWDG被激活时,当7位递减计数器(T[6:0])由0x40递减到0x3F时,会产生一个复位周期,把复位引脚拉低产生复位,如果在计数器值大于窗口寄存器值时刷新计数器也会产生一个复位。WWDG模块框图如下:


WWDG理解和应用可分为以下几部分:
  • WWDG相关的寄存器一共有两个:
    • WWDG_CR
    • WWDG_WR
  • 开启WWDG的方法有两种:
    • 软件开启:选项字节WWDG_HW位为0,WWDG由软件启动,此时系统在复位后WWDG 处于关闭状态,设置WWDG_CR的WDGA位开启WWDG,在下次复位之前WWDG不能被 关闭
    • 硬件使能:选项字节WWDG_HW位为1,WWDG由硬件启动,WDGA位不起作用
  • WWDG_CR用于设置计数器值,范围在0x7F~0x40(WWDG_CR的最高位为WDGA,用于使能,而WWDG_CR的计数器是7位的T[6:0],且当WWDG_CR < 0x40时就会产生复位)
  • WWDG_WR用于设置窗口值,WWDG有个特点是:只有计数器值小于窗口值大于0x3F时更新WWDG_CR寄存器计数值才有效,否则会产生复位
  • 设计WWDG时,如果不想考虑WWDG_WR值的影响可以把WWDG_WR的值设为大于等于WWDG_CR值。
  • WWDG的时钟为系统时钟的12288分频:fSYSCLK/12288
WWDG的时间图如下:


WWDG的时间设置例子图如下:


2、WWDG应用2.1 WWDG配置本小节介绍如何使用WWDG,并通过KEY来触发一次WWDG复位,然后通过LED2来表示(LED2表示有IWDG复位产生)。使用的例程:STM8L051F3_16_WWDG。例程的内容为:配置LED1&LED2,配置EXTI,配置WWDG(溢出时间约为393ms),在主函数中每300ms对LED1状态取反和WWDG进行刷新一次以防止系统复位,并且检测标志位。当KEY按下时进入中断,标志位被置位,循环中检测到标志位不为0,进入死循环,从而WWDG没有刷新导致系统复位,复位后在主函数初始化时检测有IWDG复位发生,LED2点亮。
2.2 例程介绍IWDG配置函数(在main.c文件下)如下所示:
static void WWDG_Config(void)
{
  /* 初始化WWDG,窗口值设为0x7f,计数器值设为0x7f,溢出时间393.216ms */
  WWDG_Init(COUNTER_INIT, WINDOW_VALUE);
}
主函数如下:
void main(void)
{
  LED_Init();   //初始化LED
  EXTI_Init();  //EXTI初始化
  enableInterrupts();   //开总中断
  /* 检测系统是否有WWDG复位产生 */
if(RST_GetFlagStatus(RST_FLAG_WWDGF)!= RESET)
{
    /* 是:点亮LED2 */
    GPIO_ResetBits(LED2_GPIO_PORT, LED2_GPIO_PINS);
    /* 清除标志位 */
    RST_ClearFlag(RST_FLAG_WWDGF);
}
else
    /* 否:关闭LED2 */
    GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PINS);
  WWDG_Config();//初始化看门狗
while(1)
{
if(EXTI_Flags != 0) //检测标志位
{
      EXTI_Flags = 0;   //标志位清零
while(1);
}
    delay_ms(300);
    GPIO_ToggleBits(LED1_GPIO_PORT, LED1_GPIO_PINS); //切换LED1状态
    WWDG_SetCounter(COUNTER_INIT);      //每300ms后喂狗一次
}
}
中断函数(位于stm8l15x_it.c)如下:
INTERRUPT_HANDLER(EXTI4_IRQHandler,12)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
  //清除中断标志位
  EXTI_ClearITPendingBit(EXTI_IT_Pin4);
  //延迟消抖
  delay_ms(10);
  //松手检测
while(GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PINS)== 0);
  //标志位置1
  EXTI_Flags = 1;
}
使用ST-LINK把程序下载到开发板,LED1闪烁,按一下KEY(长按效果一样),LED2亮。

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:21ic公开课专区:http://open.21ic.com/ 21ic资料下载中心:http://dl.21ic.com/ 21ic项目外包中心:http://project.21ic.com/ 杰杰欢迎大家有空常来赛事专区逛逛

131

主题

3790

帖子

63

粉丝