STM32有两个看门狗,一个是独立看门狗另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬,本章我们主要分析独立看门狗的功能框图和它的应用。独立看门狗用通俗一点的话来解释就是一个12位的递减计数器,当计数器的值从某个值一直减到0的时候,系统就会产生一个复位信号,即 IWDG_RESET。如果在计数没减到0之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。看门狗功能由VDD电压域供电,在停止模式和待机模式下仍能工作。

    1. /*
    2. * 设置 IWDG 的超时时间
    3. * Tout = prv/40 * rlv (s)
    4. * prv可以是[4,8,16,32,64,128,256]
    5. * prv:预分频器值,取值如下:
    6. * @arg IWDG_Prescaler_4: IWDG prescaler set to 4
    7. * @arg IWDG_Prescaler_8: IWDG prescaler set to 8
    8. * @arg IWDG_Prescaler_16: IWDG prescaler set to 16
    9. * @arg IWDG_Prescaler_32: IWDG prescaler set to 32
    10. * @arg IWDG_Prescaler_64: IWDG prescaler set to 64
    11. * @arg IWDG_Prescaler_128: IWDG prescaler set to 128
    12. * @arg IWDG_Prescaler_256: IWDG prescaler set to 256
    13. *
    14. * rlv:预分频器值,取值范围为:0-0XFFF
    15. * 函数调用举例:
    16. * IWDG_Config(IWDG_Prescaler_64 ,625); // IWDG 1s 超时溢出
    17. */
    18. void IWDG_Config(uint8_t prv ,uint16_t rlv)
    19. {
    20. // 使能 预分频寄存器PR和重装载寄存器RLR可写
    21. IWDG_WriteAccessCmd( IWDG_WriteAccess_Enable );
    22. // 设置预分频器值
    23. IWDG_SetPrescaler( prv );
    24. // 设置重装载寄存器值
    25. IWDG_SetReload( rlv );
    26. // 把重装载寄存器的值放到计数器中
    27. IWDG_ReloadCounter();
    28. // 使能 IWDG
    29. IWDG_Enable();
    30. }
    31. // 喂狗
    32. void IWDG_Feed(void)
    33. {
    34. // 把重装载寄存器的值放到计数器中,喂狗,防止IWDG复位
    35. // 当计数器的值减到0的时候会产生系统复位
    36. IWDG_ReloadCounter();
    37. }
    1. int main(void)
    2. {
    3. // 配置LED GPIO,并关闭LED
    4. LED_GPIO_Config();
    5. Delay(0X8FFFFF);
    6. /*------------------------------------------------------------*/
    7. /* 检查是否为独立看门狗复位 */
    8. if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
    9. {
    10. /* 独立看门狗复位 */
    11. /* 亮红灯 */
    12. LED_RED;
    13. /* 清除标志 */
    14. RCC_ClearFlag();
    15. /*如果一直不喂狗,会一直复位,加上前面的延时,会看到红灯闪烁
    16. 在1s 时间内喂狗的话,则会持续亮绿灯*/
    17. }
    18. else
    19. {
    20. /*不是独立看门狗复位(可能为上电复位或者手动按键复位之类的) */
    21. /* 亮蓝灯 */
    22. LED_BLUE;
    23. }
    24. /*--------------------------------------------------------------*/
    25. // 配置按键GPIO
    26. Key_GPIO_Config();
    27. // IWDG 1s 超时溢出
    28. IWDG_Config(IWDG_Prescaler_64 ,625);
    29. //while部分是我们在项目中具体需要写的代码,这部分的程序可以用独立看门狗来监控
    30. //如果我们知道这部分代码的执行时间,比如是500ms,那么我们可以设置独立看门狗的
    31. //溢出时间是600ms,比500ms多一点,如果要被监控的程序没有跑飞正常执行的话,那么
    32. //执行完毕之后就会执行喂狗的程序,如果程序跑飞了那程序就会超时,到达不了喂狗
    33. //的程序,此时就会产生系统复位。但是也不排除程序跑飞了又跑回来了,刚好喂狗了,
    34. //歪打正着。所以要想更精确的监控程序,可以使用窗口看门狗,窗口看门狗规定必须在
    35. //规定的窗口时间内喂狗。
    36. while(1)
    37. {
    38. // 这里添加需要被监控的代码,如果有就去掉按键模拟喂狗,把按键扫描程序去掉
    39. //--------------------------------------------------------------------------
    40. if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )
    41. {
    42. // 喂狗,如果不喂狗,系统则会复位,LED1则会灭一次,如果在1s
    43. // 时间内准时喂狗的话,则绿会常亮
    44. IWDG_Feed();
    45. //喂狗后亮绿灯
    46. LED_GREEN;
    47. }
    48. }
    49. //---------------------------------------------------------------------------
    50. }
    51. static void Delay(__IO uint32_t nCount) //简单的延时函数
    52. {
    53. for(; nCount != 0; nCount--);
    54. }