看门狗——用于检测单片机程序运行状态的模块或芯片

在由单片机构成的微型计算机系统中
由于外界电磁场的干扰,会造成程序的跑飞,陷入死循环
所以需要看门狗来实时检测单片机运行状态

检测原理

  1. 向键值寄存器写入 0xcccc,开始启用独立看门狗,此时计时器开始从复位值(oxfff)递减,当尾值达到 0x000 时产生复位信号
  2. 任何时候,只要在键值寄存器中写入 0xaaaa(喂狗),自动装载寄存器的值就会查询加载到计时器,从而避免看门狗复位
  3. 如果程序异常,就会无法正常按时喂狗,从而使计时器尾值达到 0x000 产生复位信号,使系统复位

需要解决的问题

  • 程序正常运行时,系统不能复位
  • 系统跑飞时(程序异常执行),复位系统,重新执行程序

STM32内置两种

  • 独立看门狗(IWDG)
    由专门的低速时钟(LS I)驱动
    即时主时钟发生故障,任然有效
    适合需要看门狗作为一个在主程序之外能够完全独立工作,且对时间精度要求低的情况
  • 窗口看门狗()
    由APB1指针分频后得到的时钟驱动
    通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作
    适合要求看门狗在精确计时窗口起作用

独立看门狗

IWDG = Internal Watchdog=内部的 看狗
相关的库函数和定义分布在文件 stm32f10x_iwdg.h 和 stm32f10x_iwdg.c 中

操作看门狗要用到的库函数

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护,可以使用寄存器了
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//设置预分频系数,向PR寄存器写入值
void IWDG_SetReload(uint16_t Reload);//设置重装载值,向RLR寄存器写入值
void IWDG_ReloadCounter(void);//喂狗
void IWDG_Enable(void);//使能看门狗
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//获取状态

操作步骤

  1. 取消寄存器写保护

access——通道,机会,权力

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
  1. 设置独立看门狗的预分频系数,确定时钟

prescaler——预分频器

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
  1. 设置看门狗的重装载值,确定溢出时间

reload——重新装入

void IWDG_SetReload(uint16_t Reload);
  1. 使能看门狗
void IWDG_Enable(void);
  1. 应用程序喂狗

counter——计时器

void IWDG_ReloadCounter(void);

代码

建立好 iwdg.c 和 iwdg.h 后

在 iwdg.h 中

#ifndef __WDG_H
#define __WDG_H
#include "sys.h"//引入其他系统头文件
void IWDG_Init(u8 prer,u16 rlr);
#endif

之后向 FWILB 文件夹中手动 add stm32f10x_iwdg.c (位于scr下)并编译

在 iwdg.c 中

#include "iwdg.h"
//prer:分频数:0~7(只有低 3 位有效!)
//分频因子=4*2^prer.但最大值只能是 256!
//rlr:重装载寄存器值:低 11 位有效.
//复位时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). 40ms是个估值  
//超过复位时间不喂的话, 会复位系统 
void IWDG_Init(u8 prer,u16 rlr)//初始化看门狗
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//取消寄存器写保护
	IWDG_SetPrescaler(prer );//该参数要从外部传入
	IWDG_SetReload(rlr );//也需要从外部传入
	IWDG_ReloadCounter();//没有参数
	IWDG_Enable();//也没有参数
}

两个参数

  • 设置预分频数
  • 设置重装寄存器值

java代码中的应用redission看门狗_#include


通过计算式 Tout=((4*2^prer)*rlr)/40 (ms) 可知

当复位时间为 1s 时

设置预分频数=4 ,重装寄存器值=625

在 main.c 中

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "iwdg.h"//因为要使用到看门狗,需要引入看门狗的头文件

 int main(void)
 {	
	u8 t=0;	  
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	 	//初始化与LED连接的硬件接口
	KEY_Init();          	//初始化与按键连接的硬件接口
	delay_ms(200);
	LED0=0;					//点亮LED
	 
	 IWDG_Init(4,625);//调用看门狗的初始化
	 /*当到达复位时间后还没有手动按下按键,系统会复位,使LED灯闪烁
	 一直在1s内按按键时LED灯则会一直灭*/
	while(1)//这里设置为了手动按按键来喂狗(便于观察效果),一般是程序执行喂狗操作 
	{
		if(KEY_Scan(0)==WKUP_PRES)//当没有在一秒内按下按键,看门狗就会复位系统 
		{		
			IWDG_ReloadCounter();//当检测到按键按下时,进行喂狗操作
		}
	}
}

其他文件根据需要建立