【STM32】看门狗

news2024/11/17 20:47:12

1.看门狗简介

看门狗起始就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新恢复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的简单一点,看门狗就是能让程序出问题时能重新启动系统。STM32有两个看门狗,独立看门狗和窗口看门狗。

1.1独立看门狗(Independent Watchdog,IWDG)

独立看门狗号称宠物狗,它有一个12位的递减计数器,当计数器的值从某个值一直减到0的时候,系统就会产生一个复位信号,即IWDG_RESET。如果在计数器没有减到0之前,刷新了计数器的值,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。

1.2独立看门狗时钟

独立看门狗的时候由独立的RC振荡器LSI提供,即使主时钟发生故障它仍然有效,非常独立。LSI的频率一般在30~60KHz之间,所以独立看门狗的定时时间并不一定非常准确,只适用于对时间精度要求比较低的场合。

在这里插入图片描述

上图中,配置的IWDG时钟CK_IWDG=32KHz。

1.3独立看门狗计数器时钟

递减计数器的时钟由LSI经过一个8位的预分频器得到,我们可以操作预分频器寄存器IWDG_PR来设置分频因子,分频因子可以是:[4,8,16,32,64,128,256],计数器时钟CK_CNT=CK_IWDG/IWDG_PR。

1.4重装载寄存器

重装载寄存器是一个12位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立看门狗的溢出时间。超时时间Tout=1/CK_CNT*rlv,rlv是重装载寄存器的值。

若IWDG_PR=32,rlv=2000,所以CK_CNT=32KHz/32=1KHz,Tout=1/1000*2000=2s。意味着2s之内我们就得喂狗,不然系统就会重启。

1.5标准库演示
#ifndef __BSP_IWDG_H
#define __BSP_IWDG_H

#ifdef __cplusplus
extern "C"{

#endif

#include "stm32f4xx.h"

void Init_IWDG(uint8_t prv,uint16_t rlv);
void IWDG_Feed(void);
	
#ifdef __cplusplus
}
#endif

#endifc
#include "bsp_iwdg.h"

/*
* 设置 IWDG 的超时时间
* Tout = prv/LSICLK * rlv (s)
*      prv可以是[4,8,16,32,64,128,256]
* prv:预分频器值,取值如下:
*     @arg IWDG_Prescaler_4: IWDG prescaler set to 4
*     @arg IWDG_Prescaler_8: IWDG prescaler set to 8
*     @arg IWDG_Prescaler_16: IWDG prescaler set to 16
*     @arg IWDG_Prescaler_32: IWDG prescaler set to 32
*     @arg IWDG_Prescaler_64: IWDG prescaler set to 64
*     @arg IWDG_Prescaler_128: IWDG prescaler set to 128
*     @arg IWDG_Prescaler_256: IWDG prescaler set to 256
*
*    独立看门狗使用LSI作为时钟。
*    LSI 的频率一般在 30~60KHZ 之间,根据温度和工作场合会有一定的漂移,我
*    们的STM32F407中为32KHz,所以独立看门狗的定时时间并不一定非常精确,只适用于对时间精度
*    要求比较低的场合。
*
* rlv:预分频器值,取值范围为:0-0XFFF
* 函数调用举例:
* Init_IWDG(IWDG_Prescaler_32 ,1000);  // IWDG 1s 超时溢出
*            (32/LSICLK)*1000 = 1s
*/
void Init_IWDG(uint8_t prv,uint16_t rlv)
{
	// 使能 预分频寄存器PR和重装载寄存器RLR可写
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	// 设置预分频器值
	IWDG_SetPrescaler(prv);
	
	// 设置重装载寄存器值
	IWDG_SetReload(rlv);
	
	// 把重装载寄存器的值放到计数器中
	IWDG_ReloadCounter();
	
	// 使能 IWDG
	IWDG_Enable();
}

void IWDG_Feed(void)
{
    // 把重装载寄存器的值放到计数器中,喂狗,防止IWDG复位
    // 当计数器的值减到0的时候会产生系统复位
    IWDG_ReloadCounter();
}

int main(void)
{
	Init_LED();
	
//	//设置中断分组
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//	
//	Init_USART();
	
	Init_IWDG(IWDG_Prescaler_32,1000);
	
  /* Infinite loop */
  while (1)
  {
  }
}

上述代码思路为:Init_LED()中会将LED点亮,然后开启独立看门狗,设置的溢出时间为1s,那么1s后由于没有喂狗,mcu会复位,LED也会灭,但是由于时间太快了,肉眼应该无法看到。所以,我们使用了示波器进行测试LED的输入电平。

在这里插入图片描述

int main(void)
{
	Init_LED();
	
//	//设置中断分组
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//	
//	Init_USART();
	
	Init_IWDG(IWDG_Prescaler_32,1000);
	
  /* Infinite loop */
  while (1)
  {
	  IWDG_Feed();
  }
}

如果我们在巡航中一直喂狗,那么mcu就不会复位。

2.窗口看门狗(Window Watchdog,WWDG)

窗口看门狗号称警犬,它也有一个递减计数器不断的往下递减计数,当减到一个固定值0x40时还不喂狗的话,就会产生复位,这个值叫窗口的下限,是固定值,不能改变。不同的是,窗口看门狗的计数器在减到某一个数之前喂狗也会产生复位,这个值叫窗口的上限,上限值由用户独立设置。窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗,这就是窗口看门狗中窗口两个字的含义。

IWDG与WWDG区别

RLR是重装载寄存器,用来设置独立看门狗的计数器的值。TR是窗口看门狗的计数器的值,由用户独立设置,WR是窗口看门狗的上窗口值,由用户独立设置。

在出现下述两种情况之一时产生看门狗复位:

  1. 当喂狗的时候如果计数器的值大于窗口上限值。
  2. 当计数器的数值从0x40减到0x3F。

如果启动了看门狗并且使能中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),这个中断我们称它为死前中断或者叫遗嘱中断, 在中断函数里面我们应该出来最重要的事情,而且必须得快,因为递减计数器再减一次,就会产生系统复位。

注意事项:

  1. 上限值必须大于0x40,否则就无窗口了。
  2. 窗口看门狗时钟来源PCLK1(APB1总线时钟)分频后。
2.1标准库演示
#ifndef __BSP_WWDG_H
#define __BSP_WWDG_H

#ifdef __cplusplus
extern "C"{

#endif

#include "stm32f4xx.h"

#define WWDG_CNT    0x7F

void Init_WWDG(uint8_t tr, uint8_t wr, uint32_t prv);
void WWDG_Feed(void);

#ifdef __cplusplus
}
#endif

#endif


#include "bsp_wwdg.h"
#include "stdio.h"

/* WWDG 配置函数
* tr :递减计时器的值, 取值范围为:0x7f~0x40
* wr :窗口值,取值范围为:0x7f~0x40
* prv:预分频器值,取值可以是
*      @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
*      @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
*      @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
*      @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
*/
void Init_WWDG(uint8_t tr, uint8_t wr, uint32_t prv)
{
	//使能窗口看门狗时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
	
	// 设置预分频器值
	WWDG_SetPrescaler(prv);
	
	// 设置重装载寄存器值
	WWDG_SetWindowValue(wr);
	
	// 使能 WWDG
	WWDG_Enable(WWDG_CNT&tr);
	
	//配置中断控制器并使能中断
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=WWDG_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStruct);
	
	WWDG_ClearFlag();//清楚标志位
	WWDG_EnableIT();//使能中断
}

void WWDG_IRQHandler(void)
{
	WWDG_SetCounter(WWDG_CNT);
	WWDG_ClearFlag();
}

void WWDG_Feed(void)
{
	printf("WWDG_Feed\r\n");
    // 把重装载寄存器的值放到计数器中,
    WWDG_SetCounter(WWDG_CNT);
}

int main(void)
{
	Init_USART();
	
	Init_LED();
	
	//设置中断分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
		
	Init_WWDG(0x7f,0x5f,WWDG_Prescaler_8);
	
	printf("hello,this is stm32f407\r\n");
  /* Infinite loop */
  while (1)
  {
        //-----------------------------------------------------
        // 这部分应该写需要被WWDG监控的程序,这段程序运行的时间
        // 决定了窗口值应该设置成多大。
        //-----------------------------------------------------
      
	    // 计时器值,初始化成最大0X7F,当开启WWDG时候,这个值会不断减小
        // 当计数器的值大于窗口值时喂狗的话,会复位,当计数器减少到0X40
        // 还没有喂狗的话就非常非常危险了,计数器再减一次到了0X3F时就复位
        // 所以要当计数器的值在窗口值和0X40之间的时候喂狗,其中0X40是固定的。
        if ( (WWDG->CR & 0X7F) < 0x5f )
		{
            // 喂狗,重新设置计数器的值为最大0X7F
            WWDG_Feed();
        }
  }
}

注意,我们试过了在死前中断中喂狗,但是好像来不及,mcu还是重启了。所以,我们在main函数中进行了计数判断喂狗。

主函数中我们把WWDG的计数器的值设置 为0X7F,上窗口值设置为0X5F,分频系数为8分频。在while死循环中,我们不断读取计数器的值, 当计数器的值减小到小于上窗口值的时候,我们喂狗,让计数器重新计数。

在while死循环中,一般是我们需要监控的程序,这部分代码的运行时间,决定了上窗口值应该设置为多少,当监控的程序运行完毕之后, 我们需要执行喂狗程序,比起独立看门狗,这个喂狗的窗口时间是非常短的,对时间要求很精确。如果没有在这个窗口时间内喂狗的话, 那就说明程序出故障了,会产生提前唤醒中断,最后系统复位。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1867928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】K-means++: 一种改进的聚类算法详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 K-means: 一种改进的聚类算法详解引言1. K-means算法回顾1.1 基本概念1.2 局限性…

2024智能驾驶兴趣人群研究报告

来源&#xff1a;百分点舆情中心 近期历史回顾&#xff1a; 劳动力效能提升指引白皮书》人效研究院.pdf 【标准】企业ESG管理体系(T-CERDS 5—2023).pdf 【实用标准】GB_T 43868-2024 电化学储能电站启动验收规程.pdf 【实用模板】用户侧新型储能项目管理流程图及备案资料清单…

搭建大型分布式服务(四十)SpringBoot 整合多个kafka数据源-支持生产者

系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目&#xff0c;每天处理上亿级的数据的精简小插件&#xff0c;快速上手。 <dependency><groupId>io.github.vipjo…

【数据同步】什么是ETL增量抽取?

目录 一、什么是ETL增量抽取 二、企业如何应用ETL增量抽取 三、如何进行ETL增量抽取 1.基于时间戳的增量抽取 2.基于主键的增量抽取 在当今信息化时代&#xff0c;数据的快速增长和多样化使得企业面临着巨大的数据管理挑战。为了高效地处理和利用数据&#xff0c;ETL&#xff0…

每日一题——Python实现PAT乙级1058 选择题(举一反三+思想解读+逐步优化)6千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码点评 时间复杂度分析 空间复杂度分析 总结 我要更强 空间复杂度优…

【学习】开发板接口

工作用到机器的开发板 有如上三个接口 。最右是仿真器&#xff0c;中间是RS232串口&#xff0c;最左是电源线 仿真器 这个是仿真器 接入机器那端用的是SWD模式&#xff0c;另一端通过USB接电脑&#xff08;这小肥手拍的怪好看&#xff09;仿真口连接了四条线分别是 VCC&#…

gsap动画库对threejs模型的应用

前言 公司的一个3D编辑器项目&#xff0c;要在three模型上加一些补间动画。做了一些调研&#xff0c;最终选择了gsap&#xff0c;其丰富的缓动函数&#xff0c;强大的动画效果和兼容性&#xff0c;更适合公司的需求。 查看gsap文档&#xff0c;发现所有的例子都是针对dom元素…

【乐吾乐2D可视化组态编辑器】文件

1 文件 文件&#xff1a;文件的新建、打开、导入、保存、另存为、下载JOSN文件、下载ZIP打包文件、导出为HTML、导出为Vue2组件、导出为Vue3组件、导出为React组件&#xff08;老版将不再维护&#xff09;、下载为PNG、下载为SVG 乐吾乐2D可视化组态编辑器demo&#xff1a;ht…

振动分析-5-基于CNN的机械故障诊断方法

参考基于CNN的机械故障诊断方法 CNN之图像识别 预训练模型迁移学习&#xff08;Transfer Learning&#xff09; 基于卷积神经网络&#xff08;CNN&#xff09;的深度迁移学习在声发射&#xff08;AE&#xff09;监测螺栓连接状况的应用 参考基于CNN的机械故障诊断所面临的困难和…

安装GroudingDINO RuntimeError: Error compiling objects for extension,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

头条系统-05-延迟队列精准发布文章-概述添加任务(db和redis实现延迟任务)、取消拉取任务定时刷新(redis管道、分布式锁setNx)

文章目录 延迟任务精准发布文章1)文章定时发布2)延迟任务概述2.1)什么是延迟任务2.2)技术对比2.2.1)DelayQueue2.2.2)RabbitMQ实现延迟任务2.2.3)redis实现 3)redis实现延迟任务4)延迟任务服务实现4.1)搭建heima-leadnews-schedule模块4.2)数据库准备4.3)安装redis4.4)项目集成…

智能革新:AI写作工具如何重塑论文生成的艺术

在学术探索的征途中&#xff0c;AI论文工具本应是助力前行的风帆&#xff0c;而非让人陷入困境的漩涡。我完全理解大家在面对论文压力的同时&#xff0c;遭遇不靠谱AI工具的沮丧与无奈。毕竟&#xff0c;时间可以被浪费&#xff0c;但金钱和信任却不可轻弃。 作为一名资深的AI…

3. 向索引库中导入数据

1. 准备数据库对象 import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstr…

sheng的学习笔记-hive框架原理

需要学习的前置知识&#xff1a;hadoop 可参考 sheng的学习笔记-hadoop-CSDN博客 相关网址 官网&#xff1a;http://hive.apache.org 文档&#xff1a;https://cwiki.apache.org/confluence/display/Hive/GettingStarted https://cwiki.apache.org/confluence/display/Hive/…

Arcgis 计算经纬度坐标并补齐6位小数

工作中我们经常需要在Arcgis中计算点的经纬度或者线的起点、终点坐标&#xff0c;为确保数据的准确性&#xff0c;我们必须保留6位小数&#xff0c;但我们在默认计算的时候偶尔会遇到算出来的经纬度坐标小数位不足6位&#xff0c;那我们应该如何补齐呢&#xff0c;这里我将方法…

EE trade:贵金属投资的优点及缺点

贵金属(如黄金、白银、铂金和钯金)一直以来都是重要的投资和避险工具。它们具有独特的物理和化学特性&#xff0c;广泛应用于各种行业&#xff0c;同时也被视为财富储备。在进行贵金属投资时&#xff0c;了解其优点和缺点对于做出明智的投资决策至关重要。 一、贵金属投资的优…

【C++练级之路】【Lv.25】智能指针

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 一、智能指针的引入二、智能指针的概念1.1 RAII1.2 指针特性1.3 拷贝问题1.4 auto_ptr 三、智能指针的模拟实…

Linux基础 - 使用 ssh 服务管理远程主机(window linux vscode)

目录 零. 简介 一. 打开linux shh 二. window连接linux 三. linux连接linux 四. VSCode远程 零. 简介 SSH&#xff08;Secure Shell&#xff09;服务是一种网络协议&#xff0c;主要用于在不安全的网络环境中为计算机之间的通信提供安全的加密连接。 SSH 服务具有以下重要…

git 中有关 old mode 100644、new mode 10075的问题解决小结

问题&#xff1a; 同一个文件被修改后&#xff0c;最后代码没有变&#xff0c;文件变了&#xff0c;导致提交了一个空文件 git diff 提示 filemode 发生改变&#xff08;old mode 100644、new mode 10075&#xff09; 解决办法 &#xff1a; 原来是 filemode 的变化&#xff…

[leetcode]first-unique-character-in-a-string 字符串中的第一个唯一字符

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int firstUniqChar(string s) {unordered_map<int, int> frequency;for (char ch: s) {frequency[ch];}for (int i 0; i < s.size(); i) {if (frequency[s[i]] 1) {return i;}}return -1;} };