STM32学习100步之第九十四-九十五步——看门狗

看门狗

看门狗是什么

看门狗定时器(WDT, Watch Dog Timer)是单片机的一个组成部分,
它实际上是一个计数器,一般给看门狗计数值,程序开始运行后看门狗开始倒计数。如果程序运行正常,过一段时间CPU应发出指令让看狗复位,重新开始倒计数。如果看门狗减到0就认为程序没有正常工作,强制整个系统复位。

看门狗是一个计数器
启动后开始倒计时
每过一 段时间CPU要重新写入计数值(喂狗)?
CPU能重写计数值,表示程序运行正常
如果程序运行出错或死机,则不能重写计数值
当计数值减到0时,看狗会让整个单片机复位

看门狗的作用

看门狗的主要目的是监控单片机程序。
如果程序不断喂狗,就证明单片机工作正常。如果程序没有喂狗,就说明单片机出了问题。
看门狗不能检查问题的原因,只能通过复位单片机,让程序重新开始运行。

两种看门狗

独立看门狗

独立的看门狗是基于一个12位的递减计数器和一个8位的预分频器,它由一个内部独立的40kHz的RC振荡器提供时钟;
因为这个RC振荡器独立于主时钟,所以它可运行于停机和待机模式。它可以被当成看门狗用于在发生问题时复位整个系统,或作为一个自由定时器为应用程序提供超时管理。通过选项字节可以配置成是软件或硬件启动看狗。在调试模式下,计数器可以被冻结。
在这里插入图片描述

独立看门狗的工作原理图:

在这里插入图片描述
由图中可看出只要在计数器减到0的之前喂狗,均可使看门狗不复位单片机。

窗口看门狗

窗口看狗内有一个7位的递减计数器,并可以设置成自由运行。
它可以被当成看门狗用于在发生问题时复位整个系统。它由主时钟驱动,
具有早期预警中断功能;在调试模式下,计数器可以被冻结。

窗口看狗必须在规定的时间范围内喂狗
作用是监控单片机运行时效是否精确,独立看门狗产生复位,说明单片机已经混乱或者死机,产生中断没有意义,也无法处理中断函数的内容,窗口看门狗的主要意义是在单片机正常工作情况下,保持系统的实效性,窗口看门狗复位,只表示系统时效性不足,并不表示系统出错或死机,因为程序可以正常运行,所以可以中断函数进行收尾

在这里插入图片描述

窗口看门狗的工作原理图:

在这里插入图片描述
所谓窗口的意思便是在窗口范围之间喂狗不会使整个单片机复位,其中0x3F的值是计数器递减下边界固定值,不可改变,在0x40使会产生一个中断给单片机,在一个计数单位的时间内,在中断处理函数中处加入在复位前需要处理的工作或保存数据。

下面是两个看门狗的驱动程序以及定时时间的设定:

独立看门狗

看门狗定时时间计算公式:Tout=(预分频值*重装载值)/40 (单位:ms)
当前pre为64,rlr为625,计算得到Tout时间为1秒(大概值)。

#define pre IWDG_Prescaler_64 //分频值范围:4,8,16,32,64,128,256
#define rlr 625 //重装载值范围:0~0xFFF(4095)

void IWDG_Init(void){ //初始化独立看门狗
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作
    IWDG_SetPrescaler(pre); //设置IWDG预分频值
    IWDG_SetReload(rlr); //设置IWDG重装载值
    IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
    IWDG_Enable(); //使能IWDG
}

void IWDG_Feed(void){ //喂狗程序
    IWDG_ReloadCounter();//固件库的喂狗函数
}
公式的简单说明:
独立时钟RTC的晶振频率为40KHZ,分频之后再乘以装载值,便可得出相应的定时时间。
窗口看门狗

窗口看门狗定时时间计算公式:
上窗口超时时间(单位us) = 预分频值×(计数器初始值-窗口值)/APB1时钟频率(单位MHz)
下窗口超时时间(单位us) = 预分频值×(计数器初始值-0x3f)/APB1时钟频率(单位MHz)

#define WWDG_CNT 0x7F //计数器初始值,范围:0x40~0x7F
#define wr 0x50 //窗口值,范围:0x40~0x7F
#define fprer WWDG_Prescaler_8 //预分频值,取值:1,2,4,8

//如上三个值是:0x7f,0x50,8时,上窗口48MS,下窗口64MS。

由前面图中可得到外部晶振提供了8MHZ经分频器分频之后接入了窗口看门狗,因此计时时间便是前面的晶振经分频之后,再乘以计数的值,因为本次是计算的窗口值,因此从开始相减即可得到相应的装载值,计算得到了窗口值对应时间值以及结束的时间值

公式说明

void WWDG_Init(void);
void WWDG_NVIC_Init(void);
void WWDG_Feed(void);

void WWDG_Init(void){ //初始化窗口看门狗
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
	WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值
	WWDG_SetWindowValue(wr); //设置窗口值
	WWDG_Enable(WWDG_CNT); //使能看门狗,设置 counter
	WWDG_ClearFlag(); //清除提前唤醒中断标志位
	WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC
	WWDG_EnableIT(); //开启窗口看门狗中断
}

void WWDG_NVIC_Init(void){ //窗口看门狗中断服务程序(被WWDG_Init调用)
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 3 组 2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 2
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure); //NVIC 初始化
}

void WWDG_Feed(void){ //窗口喂狗程序
    WWDG_SetCounter(WWDG_CNT); //固件库的喂狗函数
}

void WWDG_IRQHandler(void){	//窗口看门狗中断处理程序
	WWDG_ClearFlag(); //清除提前唤醒中断标志位

	//此处加入在复位前需要处理的工作或保存数据
}
由于窗口看门狗利用了的单片机系统总线的外部时钟(比较精准,在很小的一段时间内也能喂狗),因此需要用函数 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); 开启看门狗的外部时钟。

另外需要注意窗口看门狗有中断请求信号,因此需要初始化中断,即设定中断控制向量器,为窗口看门狗配置中断、开启中断(先开启窗口看门狗定时器的中断,再开启中断控制器的中断,因为看门狗的中断连接与中断控制器,中断控制器连接于CPU,使用中断控制器,是方便所有的中断,因此需要设置、配置两个中断。)窗口看门狗的中断函数的时间是计数一次所需要的时间,因为在0x40触发中断,在0x3f处复位,在中断处理函数中进行收尾工作,即加入在复位前需要处理的工作或保存数据

图中部分图片出自洋桃电子,仅用于学习目的。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值