0 前言

    由于单片机的工作常常会受到来自外界电磁场的干扰,造成各种寄存器和内存数据混乱,会导致程序指针错误,不在程序区,取出错误的程序指令等,都会陷入死循环,程序的正常运行被打断,由单片机控制的系统无法正常工作,会造成整个系统陷入停滞状态,发生不可预料的后果。

1 简介

    STM32F4xx具有两个看门狗外设,均可用于检测并解决由软件错误导致的故障,当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。

    独立看门狗(IWDG)由其专用的低速时钟(LSI)驱动,因此,即便在主时钟发生故障时仍然保持工作状态。窗口看门狗(WWDG)时钟由APB1时钟经预分频后提供,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。

    LSI RC 可作为低功耗时钟源在停机和待机模式下保持运行,所以,在MCU进入停机或待机模式时,看门狗仍能正常运行,所以需要定时唤醒喂狗,否则,MCU复位重启。

    独立看门狗适用于那些需要看门狗作为一个在主程序外,能够完全独立工作,并且对时间精度要求较低的场合。窗口看门狗适合那些要求看门狗在精确计时窗口起作用的应用程序。

2 独立看门狗特性

  • 自由运行递减计数器
  • 时钟由独立RC振荡器提供(可在待机和停止模式下运行)
  • 当递减计数器值达到0x000时产生复位(如果看门狗已激活)

3 独立看门狗功能说明

    当通过对关键字寄存器(IWDG_KR)写入值0xCCCC启动独立看门狗时,计数器开始从复位值0xFFF递减计数。当计数器计数到终值(0x000)时会产生一个复位信号(IWDG复位)。

    任何时候将关键字0xAAAA写到IWDG_KR寄存器中,IWDG_RLR的值就会被重载到计数器,从而避免产生看门狗复位。

32kHz(LSI)频率条件下IWDG超时周期的最小值/最大值

4 IWDG寄存器

  1. 关键字寄存器(IWDG_KR)
    Key register
    STM32系列 STM32F4xx 独立看门狗(IWDG)-LMLPHP
    位31:16 保留,必须保持复位值。
    位15:0 KEY[15:0]:键值(Key value)(只写位,读为0000h)
            必须每个一段时间便通过软件对这些位写入键值AAAAh,否则当计数器计数到0时,看门狗会产生复位。
            写入键值5555h可使能对IWDG_PR和IWDG_RLR寄存器的访问
            写入键值CCCCh可启动看门狗(选中硬件看门狗选项的情况除外)
  2. 预分频寄存器(IWDG_PR)
    Prescaler registerSTM32系列 STM32F4xx 独立看门狗(IWDG)-LMLPHP
    位31:3 保留,必须保持复位值。
    位2:0 PR[2:0]: 预分频器(Prescaler divider)
        这些位受写访问保护,通过设置这些位来选择计数器始终的预分频因子,若要更改预分频器的分频系数,IWDG_SR的PVU位必须为0。
        000:4分频
        001:8分频
        010:16分频
        011:32分频
        100:64分频
        101:128分频
        110:256分频
        111:256分频
  3. 重载寄存器(IWDG_RLR)
    Reload registerSTM32系列 STM32F4xx 独立看门狗(IWDG)-LMLPHP
    位31:12 保留,必须保持复位值。
    位11:0 RL[11:0]:看门狗计数器重载值(Watchdog counter reload value)
        这些位受写访问保护,每次对IWDG_KR寄存器写入值AAAAh时,这个值就会重装载到看门狗计数器中,之后,看门狗计数器便从该装载的值开始递减计数。若要更改重载值,IWDG_SR中的RVU位必须为0。
  4. 状态寄存器(IWDG_SR)
    Status registerSTM32系列 STM32F4xx 独立看门狗(IWDG)-LMLPHP
    位31:2 保留,必须保持复位值。
    位1 RVU:看门狗计数器重载值更新(Watchdog counter reload value update)
        通过硬件将该位置1以指示重载值正在更新,只有在RVU位为0时才可更新。
    位0 PVU:看门狗预分频器值更新(Watchdog prescaler value update)
        通过硬件将该位置1以指示预分频器值正在更新,只有在PVU位为0时才可更新。

5 代码实现

/*IWDG看门狗初始化*/
void IWDTDOG_Init(void)
{
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

    IWDG_SetPrescaler(IWDG_Prescaler_256);

    IWDG_SetReload((u16)(SYSWDG_TIMEOUT * 1000 /6.4 + 0.5));

    IWDG_ReloadCounter();
}

/*使能IWDG看门狗*/
void IWDG_Enable(void)
{
    IWDG->KR = KR_KEY_ENABLE;
}

/*使能对IWDG_PR和IWDG_RLR寄存器的写访问*/
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)
{
    assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));
    IWDG->KR = IWDG_WriteAccess;
}

/*设置IWDG预分频器的值*/
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
{
    assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));
    IWDG->PR = IWDG_Prescaler;
}

/*设置IWDG的重载值*/
void IWDG_SetReload(uint16_t Reload)
{
    assert_param(IS_IWDG_RELOAD(Reload));
    IWDG->RLR = Reload;
}

/*将Reload register的值重新加载IWDG计数器,喂狗操作*/
void IWDG_ReloadCounter(void)
{
    IWDG->KR = KR_KEY_RELOAD;
}

至此,IWDG看门狗已经初始化完毕,并开启,需要调用IWDG_ReloadCounter()定时喂狗。

6 题外话

    STM32F系列的MCU看门狗开启之后是关闭不了的,所以在进入待机和停机之后,需要定时唤醒去喂狗,喂狗的时间很短,与ST确认,STM32LXXX和STM8系列,可以在进入待机和停机之前通过用户选线字节冻结看门狗。

文章参考资料:
《STM32F4xx中文参考手册》
《STM32F4xx Reference manual》

05-09 23:14