【STM32】看门狗

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

加速业务布局,30年老将加盟ATFX,掌舵运营新篇章

全球领先的差价合约经纪商ATFX日前宣布了一项重大人事任命&#xff0c;聘请业界资深人士约翰博格(John Bogue)为机构业务运营总监。约翰博格是一名行业老将&#xff0c;曾在差价合约界深耕三十余载。伴随其加入ATFX&#xff0c;相信他的深厚专业知识和从业经验将为ATFX机构业务…

HarmonyOS NEXT Developer Beta1配套相关说明

一、版本概述 2024华为开发者大会&#xff0c;HarmonyOS NEXT终于在万千开发者的期待下从幕后走向台前。 HarmonyOS NEXT采用全新升级的系统架构&#xff0c;贯穿HarmonyOS全场景体验的底层优化&#xff0c;系统更流畅&#xff0c;隐私安全能力更强大&#xff0c;将给您带来更高…

数据集的未来:如何利用亮数据浏览器提升数据采集效率

目录 一、跨境电商的瓶颈1、技术门槛2、语言与文化差异3、网络稳定性4、验证码处理和自动识别5、数据安全6、法规和合规 二、跨境电商现在是一个合适的商机吗&#xff1f;三、数据集与亮数据浏览器1、市场分析2、价格监控3、产品开发4、供应链优化5、客户分析 四、亮数据浏览器…

Jenkins流水线发布,一篇就解决你的所有疑惑

这次搭建的项目比较常规,前端是react写的,后端是springboot,并且由于是全栈开发,所以是在同一个项目中。接下来我演示下怎么用jenkins进行自动化发布。 1.jenkins必装插件 这里用到的是jenkinsFile主要是基于Groovy这个沙盒,有些前置插件。这里使用maven进行打包,所以需…

如何提高项目风险的处理效率?5个重点

提高项目风险的处理效率&#xff0c;有助于迅速识别和应对风险&#xff0c;减少风险导致的延误&#xff0c;降低成本&#xff0c;提升项目质量&#xff0c;确保项目按时交付。如果项目风险处理效率较低&#xff0c;未能及时发现和处理风险&#xff0c;导致问题累积&#xff0c;…

浏览器扩展V3开发系列之 chrome.runtime 的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.runtime API 提供了一系列的方法和事件&#xff0c;可以通过它来管理和维护 Chrome 扩展的生命…

揭示优化Prompt的秘诀:如何让API表现媲美网页版

为什么用GPT API&#xff08;GPT-3.5-turbo&#xff09;进行程序分析时&#xff0c;效果好像比网页版的GPT-3.5差一点&#xff1f;这可能有几个原因&#xff0c;咱们细说一下。 1. Prompt不同 这是最常见的问题之一。API调用时的指令&#xff08;prompt&#xff09;往往比较简…

Android13 WMS窗口层级树

1&#xff0c;认识层级树 可以通过dumpsys activity containers 看到 WMS 层级树的结构 ACTIVITY MANAGER CONTAINERS (dumpsys activity containers) ROOT typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1440,2960]#0 Displa…

【每日刷题】Day75

【每日刷题】Day75 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1833. 雪糕的最大数量 - 力扣&#xff08;LeetCode&#xff09; 2. 面试题 17.14. 最小K个数 - 力扣…

【数据库】Oracle安装报错(win10安装oracle提示环境不满足最低要求)

目录 一、问题场景&#xff1a; 二、问题描述 三、原因分析&#xff1a; 四、解决方案&#xff1a; 一、问题场景&#xff1a; 安装Oracle数据库 二、问题描述 安装之前提示&#xff08; [INS-13001]环境不满足最低要求。 是否确实要继续? &#xff09; 如图所示&…

C# unknow column “p0.TaskTypeId‘ in ‘field list‘

这个问题就是数据库出现问题&#xff0c;去 日志中去看 &#xff0c;找个具体表去 看实体类&#xff0c;与数据库中的表&#xff0c;是否存在字段。

若依项目实战------企业人力资源管理平台

一、数据库名称规范化及建表相关 1.术语名称 1.系统名称&#xff1a;企业人力资源管理平台英文翻译&#xff1a;Enterprise Human Resource Management Platform缩写&#xff1a;EHR 2.员工信息管理&#xff08;Employee Information Management 缩写&#xff1a;EIM&#…

Vue-双向数据绑定指令

v-model指令 双向数据绑定就是当数据设置给表单元素时&#xff0c;修改这个数据会修改表单元素的值&#xff0c; 修改表单元素的值同样也会修改这个数据 <body><div id"app"><input type"text" v-model"name"><p>{{name…

GPTCache:革新大模型缓存,降低成本,提升效率

GPTCache介绍 随着应用程序越来越受欢迎并遇到更高的流量水平,与 LLM API 调用相关的费用可能会变得相当可观。此外,LLM 服务的响应时间可能会很慢,尤其是在处理大量请求时。GPTCache是一个致力于构建用于存储 LLM 响应的语义缓存的项目。 项目架构 数字人助力传统客服 1…

成熟ICT测试系统与LabVIEW定制开发的比较

ICT&#xff08;In-Circuit Test&#xff09;测试系统是电子制造行业中用于电路板&#xff08;PCB&#xff09;组件检测的重要工具。市场上有许多成熟的ICT测试系统&#xff0c;如Keysight、Teradyne、SPEA等公司提供的商用解决方案。此外&#xff0c;LabVIEW作为一种强大的图形…

Dubbo运行原理

目录 Dubbo通讯协议 Dubbo负载均衡策略 RPC和HTTP有什么区别&#xff1f; 让你设计一个RPC框架&#xff0c;如何考虑数据序列化问题&#xff1f; Dubbo 是一款高性能、轻量级的开源 RPC&#xff08;远程过程调用&#xff09;框架&#xff0c;主要用于构建分布式服务和微服务…

分享一个微信管理工具

聚合管理多个微信号 1、聚合聊天 支持多微信账号消息&#xff0c;在统一端口接收回复 2、话题素材库 可提前把话题准备好用到的时候一键发送 3、朋友圈互动 支持在聊天窗口直接看到当前客户朋友圈实时点赞评论互动 批量多号添加好友 1、批量添加联系人&#xff0c;导入联系…

蓝牙模块在车载系统中的应用与集成:现状、挑战与未来展望

随着科技的快速发展&#xff0c;蓝牙技术已经深入到我们生活的方方面面&#xff0c;其中车载系统中的应用尤为显著。蓝牙模块作为一种无线通信技术&#xff0c;不仅为驾驶者提供了更加便捷的操作体验&#xff0c;同时也提升了驾驶的安全性。本文旨在分析蓝牙模块在车载系统中的…

LabVIEW在脑机接口(BCI)研究中的应用

脑机接口&#xff08;Brain-Computer Interface&#xff0c;BCI&#xff09;技术通过解读大脑活动&#xff0c;将人类思维与计算机或其他设备连接起来&#xff0c;广泛应用于神经康复、认知研究和人机交互等领域。LabVIEW作为强大的图形化编程环境&#xff0c;在BCI研究中发挥着…

Firefox 火狐浏览器现在允许您在其 Nightly 版本中选择您喜欢的 AI 聊天机器人

Firefox Nightly版本是Mozilla推出的一个特殊的频道&#xff0c;用户可以在这里试用最新的功能和更改。这个版本每天都会更新&#xff0c;并且持续发布新的功能和修复。例如&#xff0c;在2023年10月8日发布的版本中&#xff0c;引入了一个新的按钮&#xff0c;用于快速重置隐私…