当前位置: 首页 > article >正文

独立看门狗(IWDG)实验

独立看门狗简介

单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环, 看门狗电路就是为了避免这种情况的发生 。IWDG(Independent watchdog)独立看门狗,可以用来检测并解决由于软件错误导致的故障,当计数器到达给定的超时值时,会触发一个中断或产生系统复位。独立看门狗用通俗一点的话来解释就是一个 12 位的递减计数器,当计数器的值从某个值一直减到 0 的时候,系统就会产生一个复位信号,即 IWDG_RESET。如果在计数没减到 0 之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。

看门狗的作用就是在一定时间内(通过定时计数器实现) 没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启 (发送复位信号) 。

IWDG_KR寄存器

在键值寄存器 (IWDG_ KR)中写入 0xCCCC ,开始启用独立看门狗;此时计数器开始从其复位值 0xFFF 递减计数。当计数器计数到末尾 0x000 时,会产生一个复位信号 (IWDG_RESET) 。无论何时,只要键寄存器 IWDG_KR 中被写入0xAAAA ,IWDG_RLR 中的值就会被重新加载到计数器中从而避免产生看门狗复位。
IWDG_PR和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向IWDG_KR 寄存器中写入 0x5555 。 将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装载操作(即写入 0xAAAA) 也会启动写保护功能。

还有两个寄存器,一个预分频寄存器( IWDG_PR ),该寄存器用来设置看门狗时钟的分频系数 。 另一个重装载寄存器。该寄存器用来保存重装载到计数器中的值。该寄存器也是一个 32位寄存器,但是只有低 12 位是有效的 。

在这里插入图片描述

取消寄存器写保护向IWDG_KR写0X5555:

IWDG_WriteAccessCmd(IW DG_WriteAccess_Enable);

设置独立看门狗的预分频系数和重装载值:

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) //设置 IWDG 预分频值
void IWDG_SetReload(uint16_t Reload) //设置 IWDG 重装载值

看门狗溢出时间:

Tout=((4 × 2^prer) × rlr)/40

重载计数值喂狗(向 IWDG_KR 写入 0XAAAA):

IWDG_ReloadCounter(); // 按照 IWDG 重装载寄存器的值重装载 IWDG 计数器

启动看门狗(向 IWDG_KR 写入0XCCCC):

IWDG_ Enable(); // 使能 IWDG

实现目标

用两个IO口,一个用来输入喂狗信号,另外一个用来指示程序是否重启。喂狗我们采用板上的 WK_UP 键来操作,而程序重启,则是通过 DS0 来指示的。

dog.h

#ifndef __WDG_H
#define __WDG_H
#include "stm32f10x_iwdg.h"


void IWDG_Init(u8 prer,u16 rlr);
void IWDG_Feed(void);

#endif

dog.c

#include"dog.h"
void IWDG_Init(u8 prer,u16 rlr)
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //① 使能对寄存器I写操作
    IWDG_SetPrescaler(prer); //② 设置IWDG预分频值设置IWDG预分频值
    IWDG_SetReload(rlr); //② 设置IWDG重装载值
    IWDG_ReloadCounter(); // ③ 按照IWDG重装载寄存器的值重装载IWDG计数器
    IWDG_Enable(); //④ 使能IWDG
}
//喂独立看门狗
void IWDG_Feed(void)
{
  IWDG_ReloadCounter();//reload
}

main

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "dog.h"



 int main(void)
 {		
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 	LED_Init();		  	 //初始化与LED连接的硬件接口
	KEY_Init();          //按键初始化	 
	delay_ms(500);   	 //让人看得到灭
	IWDG_Init(4,625);    //与分频数为64,重载值为625,溢出时间为1s	   
	LED0=0;				 //点亮LED0
	while(1)
	{
		if(KEY_Scan(0)==WKUP_PRES)
		{
			IWDG_Feed();//如果WK_UP按下,则喂狗
		}
		delay_ms(10);
	};	 
}
  

http://www.kler.cn/news/10369.html

相关文章:

  • 第十三届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组思考+总结
  • ChatGPT宝藏插件丨装上之后,上网、语音聊天、一键分享对话……简直让你爽到起飞!
  • Java题目训练——年终奖和迷宫问题
  • 自己再造一个大规模预训练语言模型?可以的
  • 【C++】Vector
  • 软件测试培训
  • JUC源码系列-AQS的Condition的接口实现
  • 程序员在职场中如何让自己的技能快速提高,WEB前端开发工程师如何让自己快速成为团队的核心开发人员?
  • Follow My Heart Of Apirl. 2023
  • LAZADA平台开放接口的接入和参数说明(目前支持以下基本接口:item_get 获得淘宝商品详情item_search 获得淘宝商品详情)
  • 为何ChatGPT如此擅长编造故事?
  • 操作系统 - 学习笔记
  • 不一样的websocket封装简洁版
  • 设计模式之迭代器模式(C++)
  • 新品国产C2000,独立双核32位CPU,主频高达400MHz,QX320F280049
  • 数据分析-统计基础
  • 29岁,普通功能测试,我是如何在一周内拿到5份Offer的?
  • Linux 内存回收,思维导图记录
  • CMake项目使用ctest+gtest进行单元测试
  • Vulnhub:Digitalworld.local (Development)靶机
  • C++ 23 实用工具(二)绑定工具
  • 10.字符串
  • 学习机器人SLAM导航核心技术(一)
  • 网络之广播域和冲突域
  • Qt5.12实战之规则DLL导出函数使用
  • 什么是分布式锁
  • 软考第二章 数据通信基础
  • 写博客8年与人生第一个502万
  • 空间复杂度
  • Makefile第十课:Makefile编译