STM32-09-IWDG和WWDG

【STM32系列文章】

STM32-01-认识单片机
STM32-02-基础知识
STM32-03-HAL库
STM32-04-时钟树
STM32-05-SYSTEM文件夹
STM32-06-GPIO
STM32-07-外部中断
STM32-08-串口

一、STM32 IWDG

1. IWDG

  • IWDG

    Independent watchdog,即独立看门狗,本质上是一个定时器,这个定时器有一个输出端,可以输出复位信号。该定时器是一个12位的递减计数器,当计数器的值减到0的时候,就会产生一个复位信号。如果在计数没有减到0之前,重置计数器的值的话,那么就不会产生复位信号,这个动作称为喂狗

  • 作用

    异常:外界电磁干扰或者自身系统(硬件或软件)异常,造成程序跑飞.

    独立看门狗主要用于检测外界电磁干扰,或者硬件异常导致的程序跑飞问题.

    应用:在一些需要高稳定性的产品中,并且对时间精度要求较低的场合.

    独立看门狗是异常处理的最后手段,不可依赖,应在设计时尽量避免异常的发生.

  • IWDG工作原理
    在这里插入图片描述

    时钟信号来自LSI时钟,经过PSC预分频器后变为IWDG的时钟,在时钟下进行递减,当递减计数器的值计数到0时,会产生一个复位,如果期间进行喂狗,就不会产生复位。

2. IWDG框图

在这里插入图片描述

从 IWDG 框图整体认知就是,IWDG 有一个输入(时钟 LSI),经过一个 8 位的可编程预分频器提供时钟给一个 12 位递减计数器,满足条件就会输出一个复位信号。

STM32F103的独立看门狗由内部专门的40Khz低速时钟(LSI)驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部RC时钟,所以并不是准确的 40Khz,而是在30~60Khz之间的一个可变化的时钟,只是我们在估算的时候,以40Khz的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。

3. IWDG寄存器

  • 键寄存器IWDG_KR
    在这里插入图片描述

    独立看门狗的控制寄存器

    0xCCCC:开始启动独立看门狗;

    0x5555:表示允许访问IWDG_PR和IWDG_RLR寄存器;

    0xAAAA:重新装载寄存器的初值.

  • 预分频寄存器IWDG_PR
    在这里插入图片描述

  • 重装载寄存器IWDG_RLR
    在这里插入图片描述

  • 状态寄存器IWDG_SR
    在这里插入图片描述

4. IWDG寄存器操作步骤

在这里插入图片描述

5. IWDG溢出时间计算

在这里插入图片描述

最短最长超时时间
在这里插入图片描述

6. IWDG配置步骤

在这里插入图片描述

函数主要寄存器主要功能
HAL_IWDG_InitIWDG_PR/RL/KR使能IWDG,设置预分频系数和重装载值等
HAL_IWDG_RefreshIWDG_KR把重装载寄存器的值重载到计数器中,喂狗

7. 代码实现

  • 实验效果

    在配置看门狗后,LED0将常亮,如果KEY_UP按键按下,就喂狗,只要KEY_UP不停的按,看门狗就一直不会产生复位,保持LED0的常亮,一旦超过看门狗定溢出时间(Tot)还没按,那么将会导致程序重启,这将导致LED0熄灭一次。

  • 硬件连接
    在这里插入图片描述
    在这里插入图片描述

  • 软件代码

    1. IWDG初始化函数

      void iwdg_init(uint8_t prer, uint16_t rlr)
      {
          g_iwdg_handle.Instance = IWDG;
          g_iwdg_handle.Init.Prescaler = prer;  //设置IWDG分频系数
          g_iwdg_handle.Init.Reload = rlr;      //重装载值
          
          HAL_IWDG_Init(&g_iwdg_handle);   //进行初始化
      }
      
    2. 喂狗函数

      void iwdg_feed(void)
      {
          HAL_IWDG_Refresh(&g_iwdg_handle);  //重装载计数器
      }
      
    3. 主函数代码

      int main(void)
      {
          HAL_Init();                         /* 初始化HAL库 */
          sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
          delay_init(72);                     /* 延时初始化 */
          usart_init(115200);                 /* 串口初始化为115200 */
          led_init();                         /* 初始化LED */
          key_init();                         /* 初始化按键 */
          delay_ms(100);                      /* 延时100ms再初始化看门狗,LED0的变化"可见" */
          iwdg_init(IWDG_PRESCALER_64, 625);  /* 预分频数为64,重载值为625,溢出时间约为1s */
          LED0(0);                            /* 点亮LED0(红灯) */
      
          while (1)
          {
              if (key_scan(1) == 4)       /* 如果WK_UP按下,则喂狗 */
              {
                  iwdg_feed();            /* 喂狗 */
              }
      
              delay_ms(10);
          }
      }
      

      在main函数里,先初始化系统和用户的外设代码,然后先点亮LED0,在无限循环里开始获取按键的键值,按下就喂狗,不是则延时10s,继续上述操作。当1秒钟后都没测到按键按下,WDG就会产生一次复位信号,系统复位,可以看到LED0因系统复位熄灭一次,再亮。反之,当按下按键后,1秒内再按下按键,就会及时喂狗,结果就是系统不会复位,LED0也就不会闪烁。

二、STM32 WWDG

1. WWDG

  • WWGD

    window watchdog,即窗口看门狗,通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。窗口看门狗跟独立看门狗一样,也是一个递减计数器,不同的是它们的复位条件不一样。窗口看门狗产生复位信号有两个条件:

    1. 当递减计数器的数值从 0x40 减到 0x3F 时(T6 位跳变到 0)
    2. 当喂狗的时候如果计数器的值大于 W[6:0]时,此数值在 WWDG_CFR 寄存器定义
  • 本质:能产生系统复位信号提前唤醒中断的计数器

  • 喂狗:在窗口期内重装载计数器的值,防止复位

  • 作用:用于检测单片机程序运行时效是否精准,主要用于检测软件异常

  • WWDG工作原理
    在这里插入图片描述

2. WWDG框图

在这里插入图片描述

  • WWDG有一个来自RCC的PCLK1输入时钟,经过一个4096的分频器,再经过一个分频系数可选(1、2、4、8)的可编程预分频器提供时钟给一个7位递减计数器,这里有两个输出信号。结合寄存器分析窗口看门狗的上限值和下限值。W[6:0]WWDG_CFR寄存器的低7位,用于与递减计数器T[6:0]比较的窗口值,也就是我们说的上限值,由用户设置。0x40就是下限值,递减计数器达到这个值就会产生复位。T6位就是WWDG_CR寄存器的位6,即递减计数器T[6:0]的最高位。

3. WWDG寄存器

  • 控制寄存器WWDG_CR
    在这里插入图片描述

    该寄存器只有低八位有效,其中T[6:0]用来存储看门狗的计数器的值,随时更新的,每隔(4096×2 ^WDGTB[2:0])PCLK个周期减1。当该计数器的值从0x40变为0x3F的时候,将产生看门狗复位。

  • 配置寄存器WWDG_CFR
    在这里插入图片描述

    该寄存器中的EWI位是提前唤醒中断,如果该位置1,当递减计数器等于0x40时产生提前唤醒中断,我们就可以及时喂狗以避免WWDG复位。因此,我们一般都会用该位来设置中断,当窗口看门狗的计数器值减到0X40的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于1个窗口看门狗计数周期的时间(在pck1频率为36M且WDGTB为0的条件下,该时间为113us)内重新写WWDG_CR,否则,看门狗将产生复位。

  • 状态寄存器WWDG_SR
    在这里插入图片描述

4. WWDG超时时间计算

在这里插入图片描述
在这里插入图片描述

5. WWDG配置步骤

  1. WWDG工作参数初始化

    HAL_WWDG_Init()
    
  2. WWDG Msp初始化

    HAL_WWDG_MspInit()    
    
  3. 设置优先级,使能中断

    HAL_NVIC_SetPriority()
    HAL_NVIC_EnableIRQ()
    
  4. 编写中断服务函数

    WWDG_IRQHandler() 
    HAL_WWDG_IRQHandler()
    
  5. 重定义提前唤醒回调函数

    HAL_WWDG_EarlyWakeupCallback()
    
  6. 在窗口期内喂狗

    HAL_WWDG_Refresh()
    
  • 程序运行流程

    1. 初始化过程:
      在这里插入图片描述

    2. 中断处理函数调用过程:
      在这里插入图片描述

6. 代码实现

  • 功能:

    通过中断进行喂狗,必须要在113us内进行喂狗,所有的处理操作也要在这个时间段内完成。

  • 窗口看门狗初始化函数

    void wwdg_init(uint8_t tr, uint8_t wr, uint8_t fprer)
    {
        g_wwdg_handle.Instance = WWDG;
        g_wwdg_handle.Init.Counter = tr;
        g_wwdg_handle.Init.Window = wr;
        g_wwdg_handle.Init.Prescaler = fprer;
        g_wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE;
        HAL_WWDG_Init(&g_wwdg_handle);
    }
    
  • WWDG MSP回调函数

    void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
    {
        __HAL_RCC_WWDG_CLK_ENABLE();            //使能时钟
         
        HAL_NVIC_SetPriority(WWDG_IRQn, 2, 3);  //配置中断优先级
        HAL_NVIC_EnableIRQ(WWDG_IRQn);          //使能窗口看门狗中断
    }
    
  • WWDG中断服务函数

    void WWDG_IRQHandler(void)
    {
        HAL_WWDG_IRQHandler(&g_wwdg_handle);  
    }
    
  • WWDG提前唤醒回调函数

    void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
    {
        HAL_WWDG_Refresh(&g_wwdg_handle);
        LED1_TOGGLE();
    }
    
  • 主函数

    int main(void)
    {
        HAL_Init();                             /* 初始化HAL库 */
        sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
        delay_init(72);                         /* 延时初始化 */
        usart_init(115200);                     /* 串口初始化为115200 */
        led_init();                             /* 初始化LED */
    
        
        
        if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
        {
           printf("窗口看门狗复位\r\n"); 
            __HAL_RCC_CLEAR_RESET_FLAGS();
        }
        else
        {
            printf("外部复位\r\n"); 
        }
        
        delay_ms(500);
        printf("请在窗口期内喂狗\r\n");
        wwdg_init(0x7f, 0x5f, 8);  //窗口看门狗初始化
    
        while (1)
        {     
        }
    } 
    

    主函数循环内部为空,主要是通过WWDG提前唤醒回调函数中进行喂狗,并且在0x40变到0x39的113us内进行操作。

声明:资料来源(战舰STM32F103ZET6开发板资源包)

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf
  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值