STM8的看门狗

看门狗概述

看门狗的作用

  • 单片机系统在运行过程中受到干扰,可能出现死循环、程序跑飞、操作混乱等异常,为了检测异常状态并使系统恢复正常,就要用到看门狗
  • 看门狗监控着STM8的运行,如果程序运行正常,就会在规定时间内“喂狗”,保证看门狗计数器不会发生超时溢出;倘若看门狗溢出了,就表示程序异常,看门狗就会强制系统复位
  • 看门狗机制适合解决瞬时、突发的故障,但对无法通过复位解决的故障,如硬件损坏、电气故障等就没有作用

看门狗的分类

  • IWDG独立看门狗

    又称硬件看门狗,优先级更高

    实质是一个向下计数的8位计数器,其使用LSI低速内部振荡器经过分频后作为时钟源,启用后其计数值不断递减,如果在递减到0时还没有“喂狗”(即重装载计数值)就会复位

  • WWDG窗口看门狗

    又称软件看门狗,其优先级低于硬件看门狗

    与IWDG的不同在于其使用的时钟源是f​CPU,也就是说如果系统主时钟崩溃,WWDG就无效了

    而且WWDG的实现机制比IWDG复杂得多

  • 两种看门狗的配置方法不同,接下来分别介绍


独立看门狗配置流程

独立看门狗结构介绍

  • 在开始配置之前,先了解IWDG的系统结构:

    独立看门狗的结构类似先前介绍的定时器,在计时溢出之后产生操作

    而独立看门狗与定时器相比其特点是:使用的计数时钟是LSI,计数溢出后的操作是复位

    由此可知配置IWDG类似配置定时器,也需要设定分频系数与重载值来决定计数溢出的用时

独立看门狗配置简述

  1. 启动独立看门狗

    有两种启动方式:软件启用(配置IWDG_KR寄存器)和硬件启用(配置选项字节IWDG_HW)

    • 软件程序启用:当STM8上电复位后,如果用户没有修改过选项字节,那么IWDG默认由软件程序启用

      配置键寄存器IWDG_KR,向其写入0xCC以使能IWDG

      一旦使能之后,除了复位之外就不能再关闭

    • 硬件启用:配置选项字节OPT3的IWDG_HW

      配置为Independent Watchdog activated by Hardware硬件启用后,在STM8上电时IWDG就已经启用,不需要再写寄存器

  2. 配置看门狗计时参数

    决定看门狗超时时间的参数有两个:计数值(在IWDG_RLR中设置)与计数频率(IWDG_PR寄存器中决定分频系数)

    注意这两个寄存器有写保护,在修改前必须配置IWDG_KR=0x55允许修改

  3. 喂狗

    配置IWDG_KR=0xAA对看门狗进行刷新

    配置完成后需要刷新,并且在超时溢出前也需要对看门狗进行刷新,俗称“喂狗”,否则就会导致重置

独立看门狗相关寄存器

  • 键寄存器IWDG_KR

    配置IWDG最为关键的寄存器,其写入不同的内容会有不同的操作含义

    • 0xCC:启动独立看门狗
    • 0xAA:刷新独立看门狗
    • 0x55:允许对受保护的IWDG_PR和IWDG_RLR寄存器进行操作
  • 预分频寄存器IWDG_PR

    IWDG使用128kHz的LSI为时钟源,其会固定经过2分频,因此送入IWDG分频的信号是64kHz,IWDG对这个64kHz的时钟信号进行分频

image

由表可见分频系数即设定值+2作为2的幂次:即2PR[2:0]+2

  • 重装载寄存器IWDG_RLR

    用于设置计数值,共有8位,最大可设置为0xFF,最小递减到0,计数值为设定值再+1(比如寄存器设定为0时计数值为1)

IWDG超时溢出时间计算

  • 超时时间计算公式

    通过对分频系数和重载计数值的控制,就可以设定IWDG的超时的时间

    超时时间t=2×TLSI×P×R,T的单位是s

    • TLSI是频率的倒数,单位为Hz,注意LSI不稳定,不一定就是128kHz,可以使用CCO时钟输出功能进行测量,因为LSI会经过固定的2分频,因此要乘2
    • P=2PR[2:0]+2是分频系数
    • R是计数值(即重装载寄存器的设定值再加1)
  • 重装载值的配置

    由超时时间公式变形,得到用于计算应该设定RLR寄存器重装载值的公式:

    IWDG_RLR=(T×fLSI/P)-1

  • 超时时间的范围

    在频率和设定值确定的情况下,可以将超时的时间分为两类:

    • 最短超时时间:IWDG_RLR寄存器为0的情况,这时在进行一次递减就会溢出超时
    • 最长超时时间:IWDG_RLR寄存器为0xFF的情况,这时要进行256次递减才会溢出

    根据这两个数据,可以判断合适的“喂狗时间”,即刷新看门狗的时间,不及时刷新或是过快刷新都会导致工作异常

代码实现

  • 软件启动看门狗
    IWDG_KR=0xCC;//软件启动看门狗
    IWDG_KR=0x55;//解除写保护
    IWDG_PR=0;//设定4分频
    IWDG_RLR=0xFF;//设定重载值
    IWDG_KR=0xAA;//刷新IWDG配置
    //其他代码省略
    IWDG_KR=0xAA;//在设定溢出时间之前,要进行刷新
    

窗口看门狗配置流程

窗口看门狗结构介绍

  • 窗口看门狗的时钟源

    WWDG与IWDG最为明显的差异是其计数时钟使用的是fCPU而非LSI,这意味着若fCPU失效WWDG会一同失效;

    另外,WWDG会对fCPU进行固定的12288分频,因此WWDG是没有预分频寄存器的

  • 窗口看门狗的系统结构

    窗口看门狗的系统结构比起独立看门狗更为复杂:除了常规的计数部分(由WWDG_CR控制寄存器来控制启动以及计数值)外还有一个特殊的窗口寄存器用于存放窗口值

    虽有相似的计数部分,但WWDG系统具体的工作方式不只是IWDG那样计数值递减到溢出后进行复位,而是对计数值和窗口值进行比较,不同的条件会产生不同的事件,这些事件共同决定WWDG的操作,具体如下

  • 窗口看门狗复位的逻辑

    将各类条件归结为事件,可以得到进行复位的表达式:

    WWDG复位=WWDG开启×(计数值最高位递减至0+(计数值>窗口值)×WWDG_CR发生刷新事件)

    也就是说,WWDG要复位,首要条件WWDG必须是开启状态,而后有两种情况能导致复位产生

    1. 计数值最高位达到0,计数值不断递减直到其最高位为0后进行复位,类似IWDG的计数溢出后复位,即喂狗太迟
    2. 计数值>窗口值的情况下WWDG_CR被刷新,刷新WWDG_CR即喂狗,这种情况即喂狗太早

    具体的工作逻辑如图,想要系统正常运行,就要在计数达到B的区间时喂狗

    image

    由此可知配置WWDG不仅需要设定重载值来决定计数溢出的用时,还要恰当的设定窗口值

窗口看门狗配置简述

  1. 设置fCPU

    窗口看门狗的计数时钟依赖于fCPU,因此需要先设置好单片机的时钟源

    比如说,如果配置了CLK_CKDIVR=0;对HSI不进行分频,那么就会有fCPU=fMASTER=fHSI

  2. 启动窗口看门狗

    同样拥有软件和硬件两种启动方法

    • 软件启动:默认的启用方式

      配置控制寄存器WWDG_CR的WDGA位(位7)为1时即可开启看门狗

    • 硬件启动:将选项字节OPT3的WWDG_HW位配置为Window Watchdog activated by Hardware,这样一上电便会启动WWDG

  3. 配置计数值和窗口值

    在WWDG_CR的T[6:0]位配置计数值,在WWDG_WR的W[6:0]位配置窗口值

    两个值的具体配置公式见后文

  4. 喂狗

    在恰当的时间内进行喂狗以防重置

    在启动后窗口看门狗即开始计数,但是其没有自动重装载的功能,因此WWDG的喂狗事实上是在重复软件启动的代码,填入新的计数值

窗口看门狗相关寄存器

  • 控制寄存器WWDG_CR

    最高位WDGA是开启位,控制是否启动WWDG,如果配置了硬件启动方式则此位无效

    T[6:0]这剩下的7位则用作计数值的储存,每个计数周期后值递减1,需要注意的是T的取值范围有要求:(0x7F,0x40),对于计数值最高位为0时复位的情况,也就是0x40到0x3F的时候,如果这时还没有“喂狗”就会复位

    image

  • 窗口寄存器WWDG_WR

    W[6:0]用于保存窗口值,这个值会和计数值T[6:0]进行比较

    image

WWDG超时时间计算

  • WWDG的超时溢出时间

    T[6:0]与W[6:0]是有默认值的,不配置的情况下,默认为0x7H,这时溢出时间的计数公式是:t=(12288/fCPU)×64,t单位为s,fCPU单位为Hz

    由于最高位T6必须为1才不会复位,可以把公式变形为:

    t=(12288/fCPU)×(T[5:0]+1)

  • 重装载值与窗口值的配置

    根据超时溢出时间的公式,变形可得:

    T[6:0]=(t×fCPU/12288)+63

    在确定了重装载值后,就可以依此按需确定窗口值了

代码实现

  • 软件启动窗口看门狗
    WWDG_CR = 0xFF; //软件启动且T设置为0x70
    WWDG_WR = 0x50; //设定窗口值为0x50
    WWDG_CR = 0xFF; //这就是WWDG喂狗的语句,重新写入了计数值
    //注意如果直接执行此处的代码,会因为过早喂狗产生复位,喂狗要在恰当的时间
    

posted on 2025-01-06 19:33  无术师  阅读(224)  评论(0)    收藏  举报