• STM32 你不知道的看门狗细节


    看门狗简介

     你知道什么是看门狗吗?看门狗,实际上可以说就是一个简单的定时器功能,而这个定时器有一个输出端,可以输出复位信号。一般的情况下,看门狗这个定时器是给让一个比较大的初始值,然后从这个值开始递减操作,当减到0的时候·,她就会发出复位信号,复位我们的CPU.我们可以在程序正常运行的地方周期性的重置计数器的值,只要能在计数器减到0前把值重新设置,这个动作我们将其成为喂狗,这样我们就不会复位了。但是,要注意的是,如果你的程序里面有BUG,有可能在某些时候程序脱离正常的运行路线,我们称之为程序跑飞了,这样,定时器由于得不到重新初始值,有机会递减到0,产生复位信号,复位后,程序重头开始执行,所以,看门狗起到了监控CPU运行,防止MCU死机的作用。

    STM32F407系列芯片的看门狗

    1、STM32系列芯片的内置一般会有两个看门狗,为了提供到了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(有独立看门狗和窗口看门狗)可以用来安策和解决由软件错误引起的故障;当计数器达到给定的超时值的时候,触发一个中断(这个部分只适用于窗口型看门狗)或产生系统的复位。

    2、独立看门狗(IWDG)由专门的低速时钟驱动,即使主时钟发生故障他也仍然有效。

    3、窗口看门狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。

    4、IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间进度要求较低的场合。

    5、WWDG最适合那安歇要求看门狗在精度计数窗口起作用的应用程序。

    STM32F407系列独立看门狗主要性能

     独立看门狗(IWDG)由专用的低速内部时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。
    1、自由运行的递减计数器。
    2、时钟由独立的RC振荡器提供(可在停止和待机模式下工作) 。
    3、看门狗被激活后,则在计数器计数至0x000时产生复位。

    STM32F407系列独立看门狗主要功能

    1、STM32独立看门狗有一个倒计数计数器,启动看门狗之后,计数器从其复位初值0xFFF递减计数,当计数到末尾0x000的时候,便产生一个复位信号。
    2、独立看门狗有一个键值寄存器(IWDG_KR),无论何时,只要往键值寄存器写入0xAAAA,重载寄存器IWDG_RLR的值就会被重新加载到倒计数寄存器,从而避免看门狗复位。
    3、独立看门狗的溢出时间是由 预分频寄存(IWDR_PR)和IWDG_RLR决定的。

    独立看门狗相关寄存器

    键寄存器(IWDG_KR)

    寄存器的作用:配置独立卡门狗
    寄存器使用:
    往IWDG_KR 写入0x5555 :允许访问 IWDG_PR和IWDG_RLR寄存器
    往IWDG_KR 写入0xAAAA,让IWDG_RLR能传递到计数器中
    往IWDG_KR 写入0xCCCC启动看门狗

     预分频寄存器(IWDG_PR)

    作用是:设置独立看门狗的分频系数

     重装载寄存器(IWDG_RLR)

     作用是:存放独立看门狗计数器的初始值

     状态寄存器(IWDG_SR)

    作用是:反映相应功能的状态

    独立看门狗超时时间

     溢出时间计算:   Tout=((4×2^prer) ×rlr) /32 (M4)

    时钟频率LSI=32K, 一个看门狗时钟周期就是最短超时时间。 最长超时时间= (IWDG_RLR寄存器最大值)X看门狗时钟周期

    独立看门狗编程思路

    1. 先给看门狗进行初始化操作
    2. 往IWDG_KR写入0x5555:允许访问IWDG_PR和IWDG_RLR寄存器;
    3. 配置IWDG_PR和IWDG_RLR:分频,重载时间;
    4. 往IWDG写入0xcccc启动看门狗;
    5. 可以在合适的地方进行喂狗操作:往IWDG_KR写入0xAAAA(一般是主程序的while(1){}循环中)

    STM32F407窗口看门狗

    STM32F407 窗口看门狗主要性能

    可编程的自由运行递减计数器 ,条件复位

    1、当递减计数器的值小于 0x40, (若看门狗被启动)则产生复位。

    2、 当递减计数器在窗口外被重新装载, (若看门狗被启动)则产生复位。

    3、如果启动了看门狗并且允许中断,当递减计数器等于 0x40 时产生早期唤醒中断(EWI),它可以被用于重装载计数器以避免 WWDG复位。

    窗口门狗和独立看门狗区别

    1、独立看门狗   限制喂狗时间在0-x内,x由相关寄存器决定。喂狗的时间不能过晚。

    2、窗口看门狗   喂狗时间是一个有上下限的范围内(窗口),你可以通过设定相关寄存器,设定其上限时间。喂狗的时间不能过早也不能过晚。

    窗口看门狗工作示意图

     STM32F407 窗口看门狗功能

    STM32F的窗口看门狗中有一个7位的递减计数器,它会在出现下述2种情况之一时产生看门狗复位:

    1、当计数器的数值从0x40减到0x3F时

    2、当喂狗的时候如果计数器的值大于某一设定数值时,此设定数值在WWDG_CFR寄存器定义

                                                 窗口看门狗结构框图

    STM32F407 窗口看门狗相关寄存器

    控制寄存器(WWDG_CR)

    作用:设置窗口看门狗

    配置寄存器(WWDG_CFR)

    作用:配置窗口看门狗功能

     状态寄存器(WWDG_SR)

    作用:窗口看门狗状态标识位

     窗口看门狗超时时间

     说明

    对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行了刷新看门狗操作,这样的情况下一般的看门狗就检测不出来了;        如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行非正常地跳过了某些程序段的情况

    窗口看门狗编程思路

    1、窗口看门狗初始化

    2、使能窗口看门狗时钟

    3、配置WWDG_CR:设定分频值和计数器初值。

    4、配置WWDG_CFR:设定窗口看门狗窗口值。

    5、 如果需要使用中断,则配置看门狗中断以及NVIC

    5、使能窗口看门狗

    6、在适当的地方喂狗:喂狗时间为T[6:0]值大于0x3f,并且小于W[6:0],过早过晚都会产生复位。

    完整代码源

    1. #include "DG.h"
    2. #include "GPIO.h"
    3. #include "USART.h"
    4. void IWDG_INIT(void)
    5. {
    6. IWDG_WriteAccessCmd(ENABLE); //关闭写使能
    7. IWDG_SetPrescaler(IWDG_Prescaler_32); //设置分频
    8. IWDG_SetReload(1000); //设置重装载值
    9. IWDG_ReloadCounter(); //从计数器取值
    10. IWDG_Enable(); //使能看门狗计数
    11. }
    12. //窗口看门狗
    13. void WWDG_INIT(void)
    14. {
    15. RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //开时钟
    16. NVIC_InitTypeDef NVIC_InitStruct;
    17. WWDG_SetPrescaler(WWDG_Prescaler_1); //时钟频率: WWDG counter clock = (PCLK1/4096)/8;可能是1281
    18. WWDG_SetWindowValue(0x7F); //上限值0x7f
    19. WWDG_EnableIT(); //允许产生中断
    20. WWDG_Enable(0x7F); //启动窗口看门狗并加载计数器
    21. NVIC_InitStruct.NVIC_IRQChannel = WWDG_IRQn;//开启NVIC看门狗的通道管道
    22. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//将其使能
    23. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//设置抢占优先级
    24. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//设置响应优先级
    25. NVIC_Init(&NVIC_InitStruct);//将其进行初始化处理
    26. }
    27. //窗口看门狗的中断服务函数
    28. void WWDG_IRQHandler (void)
    29. {
    30. WWDG_ClearFlag(); //清除标志位
    31. if(WWDG_GetFlagStatus()==RESET)
    32. {
    33. WWDG_SetCounter(0x7F); //喂狗
    34. }
    35. }

    .h文件 

    1. #ifndef __DG_H
    2. #define __DG_H
    3. #include "stm32f4xx.h"
    4. void IWDG_INIT(void);
    5. void WWDG_INIT(void);
    6. #endif

  • 相关阅读:
    ffmpeg转码生成的m3u8格式详解
    基于xsh的vbs脚本的使用(简介)
    python发送企业微信群webhook消息(文本、文件)
    TypeORM 框架
    MyBioSource p53 肿瘤抑制蛋白 (TP53),多克隆抗体
    vue中iframe传参/绕过跨域/绕过src不刷新问题解决
    【Linux网络】2分钟学习centos7永久修改网卡名称
    Grafana变量默认全选
    如何从戴尔笔记本电脑恢复数据?
    求解哈夫曼树HuffmanTree以及C语言实现
  • 原文地址:https://blog.csdn.net/Lushengshi/article/details/126332139