0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

看门狗实验

汽车电子技术 来源:滑小稽笔记 作者:电子技术园地 2023-03-01 15:22 次阅读

14.1 STM32看门狗简介

单片机构成的微型计算机系统中,单片机的工作可能会受到外界的电磁干扰或者程序运行的BUG导致程序指针错误,或者其他错误导致的死循环,引发整个系统陷入停滞状态,所以需要一个与系统独立的定时器来监控单片机的运行状态,这个定时器在系统正常运转的时候,不停的刷新定时器的计数器,例如隔一段时间给这个定时器的计数器写100,然后在定时器减运算到0之前再一次写入100,这样,就保证了定时器不计数到0,也就意味着通过判断这个定时器是否计数到0来判断系统是否陷入死机状态,实现这种功能的定时器就称为看门狗,不停的刷新计数器值的行为就称为“喂狗”,一般计数器计数到0后会直接对单片机进行复位,用于避免系统陷入死循环。

STM32内部有两种看门狗模块,一种是窗口看门狗WWDG,另一种是独立看门狗IWDG,STM32的独立看门狗由内部专门的40Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。独立看门狗的时钟是一个内部RC时钟,所以并不是准确的40Khz,而是在30~60Khz之间的一个可变化的时钟,只是我们在估算的时候,以40Khz的频率来计算。窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器数值之前,如果7位的递减计数器数值在控制寄存器中被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。

14.2 独立看门狗相关寄存器

14.2.1 键值寄存器IWDG_KR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
KEY[15:0]

该寄存器属于只写寄存器,读取的值为0x0000,软件必须以一定间隔写入0xAAAA,否则,当计数器为0时,看门狗会产生复位;

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

写入0xCCCC表示启动看门狗工作,如果选择了硬件看门狗则不受此命令字限制。

14.2.2 预分频寄存器IWDG_PR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- PR[2:0]

Bit 2~Bit 0:预分频因子

000:预分频因子=4

001:预分频因子=8

010:预分频因子=16

011:预分频因子=32

100:预分频因子=64

101:预分频因子=128

110:预分频因子=256

111:预分频因子=256

14.2.3 重装载寄存器IWDG_RLR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- RLR[11:0]

Bit 11~Bit 0:看门狗计数器重装载值:每当向IWDG_KR寄存器写入0xAAAA时,重装载值会被传送到计数器中,随后计数器从这个值开始递减计数。

14.3 窗口看门狗相关寄存器

14.3.1 控制寄存器WWDG_CR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- WDGA T6 T5 T4 T3 T2 T1 T0

Bit 7:激活位:,此位由软件置1,但仅能由硬件在复位后清0。当WDGA=1时,看门狗可以产生复位

0:禁止看门狗

1:启用看门狗

Bit 6~Bit 0:7位计数器,存储看门狗的计数器值。每(4096x2 ^WDGTB^ )个PCLK1周期减1。当T6变成0产生看门狗复位

14.3.2 配置寄存器WWDG_CFR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- EWI TB1 TB0 W6 W5 W4 W3 W2 W1 W0

Bit 9:提前唤醒中断,此位若置1,则当计数器值达到40h,即产生中断,此中断只能由硬件在复位后清除

Bit 8:预分频器时基

00:CK计时器时钟不分频

01:CK计时器时钟2分频

10:CK计时器时钟4分频

11:CK计时器时钟8分频

Bit6~Bit 5:7位窗口值,用来与递减计数器进行比较用的窗口值

14.3.3 状态寄存器WWDG_SR

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- EWIF

Bit 0:提前唤醒中断标志,当计数器值达到40h时,此位由硬件置1。它必须通过软件写0来清除。若中断未被使能,此位也会被置1

14.4 实验例程

14.4.1 独立看门狗实验

功能:如果看门狗没有复位,接在PB5上的LED常亮,如果PA0的按键按下,就喂狗,只要按键不停的按,看门狗就一直不会产生复位,保持DS0的常亮,一旦超过看门狗定溢出时间,那么将导致程序重启,这将导致DS0熄灭一次。

(1)创建wdg.h文件输入以下代码。

#ifndef _WDG_H_
#define _WDG_H_


#include "sys.h"
/*********************************************************************************************************
                  函    数    列    表
*********************************************************************************************************/
void IWDG_Init( u8 prer, u16 rlr ) ;                                  //独立看门狗初始化


#endif

(2)创建wdg.c文件输入以下代码。

#include "wdg.h"
/***************************************************
Name    :IWDG_Init
Function  :独立看门狗初始化
Paramater  :
      prer:分频数:0~7
      rlr:重装载寄存器值
Return    :None
***************************************************/
void IWDG_Init( u8 prer, u16 rlr )
{
  IWDG->KR = 0x5555 ;                                          //使能对IWDG->PR和IWDG->RLR的写
    IWDG->PR = prer ;                                          //设置分频系数
    IWDG->RLR = rlr ;                                          //从加载寄存器 IWDG->RLR
  IWDG->KR = 0xAAAA ;                                          //更新计数器
    IWDG->KR = 0xCCCC ;                                          //使能看门狗
}

(3)在1.c文件中输入以下代码。

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "wdg.h"
/***************************************************
Name    :LED_Init
Function  :LED初始化
Parameter  :None
Return    :None
***************************************************/
#define LED PBout( 5 )                                          //定义LED端口
void LED_Init()
{
  RCC->APB2ENR |= 1<<3 ;
  GPIOB->CRL &= 0xFF0FFFFF ;
  GPIOB->CRL |= 0x00300000 ;
  LED = 1 ;
}
/***************************************************
Name    :KEY_Init
Function  :KEY初始化
Parameter  :None
Return    :None
***************************************************/
#define KEY  PAin( 0 )                                          //定义按键端口
void KEY_Init()
{
  RCC->APB2ENR |= 1<<2 ;
  GPIOA->CRL &= 0xFFFFFFF0 ;
  GPIOA->CRL |= 0x00000008;
}
/***************************************************
Name    :main
Function  :主函数
Parameter  :None
Return    :None
***************************************************/
int main()
{
  STM32_Clock_Init( 9 ) ;                                        //STM32时钟初始化
  SysTick_Init( 72 ) ;                                        //SysTick初始化
  USART1_Init( 72, 115200 ) ;                                      //初始化串口1波特率115200
  LED_Init() ;                                            //LED初始化
  KEY_Init() ;                                            //按键初始化
   delay_ms( 500 ) ;                                          //延时500ms,让人可以看到DS0灭的状态
   IWDG_Init( 4, 625 ) ;                                        //与分频数为64,重载值为625,溢出时间为1s
  LED = 0 ;                                              //点亮DS0
  while( 1 )
  {
    if( KEY==1 )
    {
      delay_ms( 10 ) ;
      if( KEY==1 )
      {
        IWDG->KR = 0xAAAA ;                                    //喂狗
      }
    }
    delay_ms( 20 ) ;
  }
}

14.4.2 窗口看门狗实验

功能:程序一运行使得接在PB5上的LED1亮300ms后关闭,进入死循环。等待WWDG中断的到来,在中断里面,喂狗,并对PE5上的LED2进行翻转操作。可以看到LED2不停的闪烁,LED1只在刚启动的时候闪一下。

(1)在上一个实验的wdg.h文件的函数列表区域添加以下代码。

void WWDG_Init( u8 tr, u8 wr, u8 fprer ) ; //窗口看门狗初始化

(2)在上一个实验的wdg.c文件末尾添加以下代码。

/***************************************************
Name    :WWDG_IRQHandler
Function  :窗口看门狗中断服务程序
Paramater  :None
Return    :None
***************************************************/
void WWDG_IRQHandler()
{
  WWDG->CR = 0x7F ;                                          //重设置7位计数器
  WWDG->SR = 0x00 ;                                          //清除提前唤醒中断标志位
  LED2 != LED2 ;
}
/***************************************************
Name    :WWDG_Init
Function  :窗口看门狗初始化
Paramater  :
      tr:计数器值
      wr:窗口值
      fprer:分频系数
Return    :None
***************************************************/
void WWDG_Init( u8 tr, u8 wr, u8 fprer )
{
  RCC->APB1ENR |= 1<<11 ;                                        //使能wwdg时钟
  WWDG->CFR |= fprer<<7 ;    //PCLK1/4096再除2^fprer
  WWDG->CFR &= 0xFF80 ;
  WWDG->CFR |= wr ;                                          //设定窗口值
  WWDG->CR |= tr&0x7F ;                                        //设定计数器值
  WWDG->CR |= 1<<7 ;                                          //开启看门狗
  NVIC_Init( 2, 3, WWDG_IRQn, 2 ) ;                                  //抢占2,子优先级3,组2
  WWDG->SR = 0x00 ;                                          //清除提前唤醒中断标志位
  WWDG->CFR |= 1<<9 ;                                          //使能提前唤醒中断
}

注:由于在中断服务函数中引用了LED2,所以需要添加头文件#include “led.h”。

(3)创建led.h文件,并输入以下代码。

#ifndef _LED_H_
#define _LED_H_


#include "sys.h"
/*********************************************************************************************************
                  硬    件    端    口
*********************************************************************************************************/
#define LED1  PBout( 5 )                                        //定义LED1端口
#define LED2  PEout( 5 )                                        //定义LED2端口
/*********************************************************************************************************
                  函    数    列    表
*********************************************************************************************************/
void LED_Init( void ) ;                                          //LED初始化


#endif

(4)创建led.c文件,并输入以下代码。

#include "led.h"


/***************************************************
Name    :LED_Init
Function  :LED初始化
Paramater  :None
Return    :None
***************************************************/
void LED_Init()
{
  RCC->APB2ENR |= 1<<3 ;
  GPIOB->CRL &= 0xFF0FFFFF ;
  GPIOB->CRL |= 0x00300000 ;

  RCC->APB2ENR |= 1<<6 ;
  GPIOE->CRL &= 0xFF0FFFFF ;
  GPIOE->CRL |= 0x00300000 ;

  LED1 = 1 ;
  LED2 = 1 ;
}

(5)在1.c文件中输入以下代码。

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "led.h"
#include "wdg.h"
/***************************************************
Name    :main
Function  :主函数
Parameter  :None
Return    :None
***************************************************/
int main()
{
  STM32_Clock_Init( 9 ) ;                                        //STM32时钟初始化
  SysTick_Init( 72 ) ;                                        //SysTick初始化
  USART1_Init( 72, 115200 ) ;                                      //初始化串口1波特率115200
  LED_Init() ;                                            //LED初始化
  LED1 = 0 ;                                              //点亮DS0
  delay_ms( 300 ) ;                                          //延时300ms,让人可以看到DS0亮的状态
   WWDG_Init( 0x7F, 0x5F, 3 ) ;                                    //计数器值为7f,窗口寄存器为5f,分频数为8
  while( 1 )
  {
    LED1 = 1 ;                                            //熄灭LED1
  }
}

14.5 为何STM32要同时存在窗口看门狗与独立看门狗

14.5.1 独立看门狗的使用条件

(1)程序跑飞

(2)出现死循环

(3)睡眠与休眠不合理

(4)外部主晶振损坏

(5)需要重新复位,且不保留任何数据

14.5.2 窗口看门狗使用条件

(1)软件逻辑出现错误

(2)死机或者死循环

(3)软件执行不按预期效果执行

(4)软件需要重新复位,但是保留所有数据

14.5.3 两者的区别

(1)独立看门狗使用内部专用40kHz低速时钟

窗口看门狗则使用PCLK1的时钟

(2)独立看门狗没有中断,超时直接复位

窗口看门狗有中断,超时可以在中断服务函数中操作或者喂狗

(3)独立看门狗一般用于避免程序跑飞或者死循环

窗口看门狗则是为了避免程序不按照预先设定的逻辑执行

(4)独立看门狗是12位递减操作

窗口看门狗则是6位递减操作
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6030

    文章

    44487

    浏览量

    631867
  • 计算机系统
    +关注

    关注

    0

    文章

    276

    浏览量

    24071
  • 程序
    +关注

    关注

    116

    文章

    3754

    浏览量

    80738
收藏 人收藏

    评论

    相关推荐

    WDT看门狗实验

    【5】WDT看门狗实验1.实验目的:掌握WDT用法,WDT的实质:监控CPU程序执行,一旦出现异常,WDT向CPU发送复位中断2.实验原理:WDT监控CPU:CPU每执行一段程序就要像
    发表于 07-23 06:36

    独立看门狗实验教程

    独立看门 看门狗实验网上有很多实验教程,比较典型的有正点原子的实验教程,野火的
    发表于 07-30 07:18

    看门狗实验有哪些操作步骤

    main.c/***********************************************************FileName: 看门狗实验**Description
    发表于 08-02 10:34

    看门狗实验概述

    看门狗实验概述也就是保证程序能正常执行,如果程序执行异常,可以使系统复位。 STM32看门狗的分类: 这次主要学习独立看门狗的相关知识,独立看门狗
    发表于 08-02 07:50

    独立看门狗实验

    独立看门狗实验
    发表于 08-02 06:25

    独立看门狗实验

    独立看门狗实验独立看门狗概述常用寄存器和库函数配置编写独立看门狗实验一. 概述在单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自
    发表于 08-02 08:01

    怎样去编写独立看门狗实验代码

    独立看门狗实验目的是什么?怎样去编写独立看门狗实验代码?如何对独立看门狗实验进行分析?
    发表于 08-05 06:01

    STM32独立看门狗实验记录

    求大神分享STM32独立看门狗实验记录
    发表于 09-24 14:47

    ALIENTEK_MINISTM32_实验5_独立看门狗实验

    ALIENTEK MINISTM32 实验5 独立看门狗实验,很好的资料,快来学习吧
    发表于 02-18 14:58 6次下载

    ALIENTEK_MINISTM32_实验6_窗口看门狗实验

    ALIENTEK MINISTM32 实验6 窗口看门狗实验,很好的资料,快来学习吧
    发表于 02-18 14:58 4次下载

    独立看门狗实验-IWDG-M3

    关于STM32独立看门狗实验文档
    发表于 11-27 15:30 3次下载

    使用STM32单片机实现独立看门狗实验的教程说明

    本文档的主要内容详细介绍的是使用STM32单片机实现独立看门狗实验的教程说明。
    发表于 01-02 08:00 3次下载
    使用STM32单片机实现独立<b class='flag-5'>看门狗</b><b class='flag-5'>实验</b>的教程说明

    2021-04-20 独立看门狗实验

    独立看门狗实验独立看门狗概述常用寄存器和库函数配置编写独立看门狗实验一. 概述在单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自
    发表于 11-25 11:06 20次下载
    2021-04-20 独立<b class='flag-5'>看门狗</b><b class='flag-5'>实验</b>

    基于STM32单片机独立看门狗实验使用库文件设计

    基于STM32单片机独立看门狗实验使用库文件设计源代码
    发表于 04-26 14:43 0次下载

    基于51单片机的内部看门狗实验例程源代码

    基于51单片机的内部看门狗实验例程源代码
    发表于 05-12 16:22 6次下载