cubeIDE开发, stm32窗口看门狗WWDG的CubeMX配置及HAL库底层实现分析

news2024/11/15 16:19:30

一、stm32的WWDG说明

       1.1  WWDG特点:

        在前一篇博文介绍独立看门狗时就指出STM32 MCU提供两个看门狗,独立看门狗和窗口看门狗。

cubeIDE开发, stm32独立看门狗IWDT的CubeMX配置及HAL库底层实现分析_py_free的博客-CSDN博客

        相比独立看门狗,窗口看门狗WWDG有以下特点:

        【1】WWDG计数器依赖于系统时钟,准确来说依赖于系统时钟通过分频、倍频得到的PCLK1时钟,即APB1 peripheral clocks输出频率。

        【2】WWDG支持中断功能以及早期唤醒中断。

        1.2 WWDG的cubeMX配置及说明

        现在看一下WWDG在CubeMX中的设置问题,WWDG和IWDG一样,在系统内核栏目开启,开启激活选项后,可以设置5项参数,分别是计数时钟分频值,窗口值、递减计数预设值、早期唤醒中断使能以及中断功能。

        【1】 一旦WWDG启用,将生成系统重置功能并启动其递减计数器,喂狗时,必须在设定的上限时间和下限时间之间喂狗,如果喂狗时间高于上限时间或者低于下限时间,都会导致看门狗触发重启机制。其中下限时间是系统固定的0X40。上限时间(窗口值)是用户可以定义的,大于0X40同时小于0X7F即可。

        【2】程序在达到0x3F值之前刷新计数器(计数器的低六位值,最大值111111=0X3F),到期时触发系统重置(即,当计数器值从0x40向下滚动到0x3F时生成重置,即再次减一时,0x40=0X3F+0X01)。并在计数器达到刷新窗口值之前刷新了计数器值,也会生成MCU重置。这就要求必须在有限的窗口中刷新计数器。另外WWDG启用后,除非通过系统重置,否则无法禁用WWDG。

        【3】如果启用了早期唤醒中断(Early Wakeup Interrupt,EWI)功能,在WWDG到期之前发出警告(即计数器达到0x40时会产生中断)。使用早期唤醒中断(EWI),在生成MCU重置之前可执行特定的安全操作或数据记录。此机制要求在NVIC中启用WWDG中断设置。同样,EWI启用后,EWI中断不能被禁用,除非通过系统重置。中断状态感知可在RCC_CSR寄存器中的WWDGRST标志判断何时发生WWDG重置。

        1.3 WWDG喂狗时间计算

        WWDG计数器输入时钟由PCLK1频率(APB1 peripheral clocks输出频率)除以计数时钟分频值得出。

         WWDG时钟(Hz)=PCLK1/(4096*预分频器);

        WWDG周期(mS)=1000/WWDG时钟(Hz);

        WWDG超时MinT(mS)=WWDG周期(mS)*(计数器-窗口),因此最好设置递减计数值≥窗口值。

        WWDG超时MaxT(mS)=WWDG周期(mS)*(计数器-0x40),0x40=0X3F+0X01;

        WWDG喂狗时间MinT(mS)<t<MaxT(mS)。

二、WWDG工程创建及源码分析

       2.1 cubeMX界面配置WWDG

         本博文基于前面独立看门狗的工程直接增加窗口看门狗功能,并关闭独立看门狗。

        双击.ioc文件打开cubeMX界面,开启WWDG,设置其参数如下,其中分频值2,窗口值0X64(100),递减计数预设值0X64(100),开启早期唤醒中断:

         开启WWDG中断功能

         APB1时钟输出频率设置10MHz(10 000 000Hz),设置该值小一些,主要是本博文采用按键触发切换喂狗时间间隔,而按键捕获到松开是人为操作,反应较慢,实时性不好体现。

         2.2 WWDG超时时间实例计算

        在WWDG的喂狗时间按前面计算公式,喂狗时间范围:

        WWDG周期(mS)=1000ms/10MHz/(4096*8)=3.2768ms。

        WWDG喂狗时间是在WWDG启动后的t时间内:

        t>3.2768ms*(0X64-0X64)=0ms;

        t<3.2768ms*(0X64-0X40)=117.9648ms。

       2.3 工程高级配置

         在工程高级配置中,取消WWDG的自动初始化,本博文将自己添加初始化,主要是HLA的WWDG初始化启动就立即进入计数,会给第一次喂狗造成时间差异较大。

        生成代码输出。

三、WWDG源码分析及应用

        3.1 WWDG的HLA库源码分析

        WWDG会在Core源码目录下的Inc及Src目录,分别生成wwdg.h和wwdg.c驱动文件。在wwdg.c文件中,主要定义了MX_WWDG_Init函数和HAL_WWDG_MspInit函数。MX_WWDG_Init主要做两件事情,一是将CubeMX上配置的参数传递给WWDG缓存Init和生成WWDG句柄Instance,二是调用HLA库的HAL_WWDG_Init来实现真正的初始化设定。HAL_WWDG_MspInit是HLA内的弱函数,根据实际配置CubeMX会生成新的函数覆盖原来的弱函数,而在HAL_WWDG_Init函数中会调用到HAL_WWDG_MspInit函数。

         在stm32l4xx_hal_wwdt.c源文件中定义了HAL_WWDG_Init函数,它做以下事情:诊断配置参数是否合规(如果不是采用CubeMX配置,而是自己手动配置或调整过参数的,这里可能异常);调用HAL_WWDG_MspInit函数完成WWDG时钟以及中断初始化;最后将依据参数写入WWDG寄存器。

         程序在依据参数将WWDG计数器值写入WWDG寄存器CR,将窗口值和时钟分频值写入WWDG寄存器CFR内。

         再回到wwdg.c内,HAL_WWDG_MspInit函数实现了WWDG时钟启动设置和中断初始及启动设置。

         HAL_NVIC_EnableIRQ启动后,如果有WWDG中断事件时,当中断服务例程触发HAL_WWDG_IRQHandler时,将自动清除标志,并执行HAL_WWDG_WakeupCallback用户回调函数报警。该回调函数在stm32l4xx_hal_wwdt.c定义,是个弱函数,用户可以通过自定义回调AL_WWDG_WakeupCallback来添加自己的代码。例如本文将在wwdg.c文件内重新定义该函数:

/* USER CODE BEGIN 1 */
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
	printf("I know, but do nothing!\r\n");
}
/* USER CODE END 1 */

         3.2 延时函数设计

        在ICore目录下添加delay目录,并在该目录下创建delay.h和delay.c源文件,实现自定义延时函数,主要满足本博文更高精度的延时要求。

        delay.h,声明微妙、毫秒、秒的延时函数。

#ifndef DELAY_DELAY_H_
#define DELAY_DELAY_H_

#include "stm32l4xx_hal.h" //HAL库文件声明

void delay_us(uint32_t us);	//延时微妙
void delay_ms(uint32_t ms);	//延时毫秒
void delay_s(uint32_t s);	//延时秒

#endif /* DELAY_DELAY_H_ */

        delay.c,

#include "delay.h"

#define MFP_VAL 8000000    //80MHz

void delay_us(uint32_t us) //利用CPU循环实现的非精准应用的微秒延时函数
{
    uint32_t delay = (HAL_RCC_GetHCLKFreq() /  MFP_VAL* us); //使用HAL_RCC_GetHCLKFreq()函数获取主频值,经算法得到1微秒的循环次数
    while (delay--); //循环delay次,达到1微秒延时
}

void delay_ms(uint32_t ms){ //mS毫秒级延时程序
	while( ms-- != 0){
		delay_us(1000);	//调用1000微秒的延时
	}
}

void delay_s(uint32_t s){ //S秒级延时程序
	while( s-- != 0){
		delay_ms(1000);	//调用1000毫秒的延时
	}
}

        3.3 WWDG使用程序设计

        在本博文中,我们设计通过按键切换喂狗时间间隔,来测试喂狗窗口及时间间隔效果。

        在main.c源文件中,添加驱动头文件,注意由于在CubeMX取消了自动初始化WWDG,因此需要手动添加wwdg.h头文件:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "wwdg.h"
#include "../../ICore/key/key.h"
#include "../../ICore/led/led.h"
#include "../../ICore/print/print.h"
#include "../../ICore/usart/usart.h"
#include "../../ICore/delay/delay.h"
/* USER CODE END Includes */

        在main主函数前,声明WWDG句柄,用于喂狗函数是调用

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
extern WWDG_HandleTypeDef hwwdg;
/* USER CODE END 0 */

        在main主函数内,设置各外设功能及手动初始化WWDG驱动。

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LPUART1_UART_Init();
  /* USER CODE BEGIN 2 */
  ResetPrintInit(&hlpuart1);
  HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断
  HLPUSART_RX_STA = 0;
  //
  printf("app restart now!\r\n");
  uint8_t wdt_flag = 1;
  uint8_t printf_flag = 1;
  MX_WWDG_Init();
  /* USER CODE END 2 */

        在main函数主循环体内,进行喂狗测试,默认是10微妙喂狗一次,按键0停止喂狗,按键1间隔10毫秒喂狗,按键2间隔1秒喂狗。注意前面计算得知0<t<117.9648ms内喂狗有效。按键1间隔10毫秒喂狗主要考虑到按键按下及松开时间效应问题,因此不能设置太大,否则可能因为按键动作耽搁时间太久无效。在实际项目中,我们通常会采用独立线程持续喂狗,各种异常触发打断喂狗来设计。

 /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(1==wdt_flag){
		  HAL_WWDG_Refresh(&hwwdg);
		  delay_us(10);//等待
	  }
	  if(2==wdt_flag){
		  HAL_WWDG_Refresh(&hwwdg);
  		  delay_ms(10);//等待
  	  }
	  if(3==wdt_flag){
		  HAL_WWDG_Refresh(&hwwdg);
		  delay_s(1);//等待
	  }
	  if(printf_flag)
	  {
		  printf("current wdt_flag=%u!\r\n",wdt_flag);
		  printf_flag = 0;
	  }
	  if(KEY_0())
	  {
		  wdt_flag = 0;
		  printf("WWDG_Refresh stop!\r\n");
		  delay_us(1);//等待
		  printf_flag =1;
	  }
	  if(KEY_1())
  	  {
		  wdt_flag = 2;
		  printf("WWDG_Refresh before WIN Time!\r\n");
		  delay_us(1);//等待
		  printf_flag =1;
  	  }
	  if(KEY_2())
  	  {
		  wdt_flag = 3;
		  printf("WWDG_Refresh after 0X40 Time!\r\n");
		  delay_us(1);//等待
		  printf_flag =1;
  	  }
    /* USER CODE END WHILE */

四、编译及测试

        4.1 编译

         4.2 测试

        打开串口助手,连接上开发板,按键0、1、2观察效果:

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

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

相关文章

【C语言】数据类型

文章目录c语言的类型整数整数类型整数的内部表达整数的范围unsigned整数的格式化浮点型浮点类型输入输出输出精度字符类型逃逸字符类型转换自动类型转换强制类型转换逻辑类型bool逻辑运算条件运算符C语言的变量,必须在使用前定义,并且确定类型&#xff1…

ubuntu下使用doxygen生成软件文档

ubuntu下使用Doxygen生成软件文档一、软件下载1.系统安装Doxygen2.Vscode插件安装二、软件配置三、文档生成1.方法1:使用Doxygen-gui生成(推荐)2.方法:采用Doxygen命令(不推荐)另外Windows下使用方法提示&a…

【JavaScript】 Date 日期对象概述及相关方法

文章目录【JavaScript】 Date 日期对象的创建及相关方法一. 日期对象的创建二. 日期对象的相关方法三. 时间戳案例案例1:在页面上展示一个时钟,隔1s更新一次案例2:距离除夕倒计时【JavaScript】 Date 日期对象的创建及相关方法 一. 日期对象…

ArcGIS基础:构建点对连线表达点集内部相互关系

原始数据如下,为普通的点图层,总共是21个点。 点位分布如下: 属性表打开如下: 下面使用【构造视线】工具进行操作,其工具位于【3D分析工具】下的【可见性】工具栏。 打开【构造视线】对话框,把【视点…

Leetcode【494. 目标和】

题目描述 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 例如,nums [2, 1] ,可以在 2 之前添加 ‘’ ,在 1 之前添加 ‘-’ &…

第10章 角色页的分页、排序、查询实现

1 重构WebApi.Controllers.RoleController. PostRolePageByFromBodyAsync //把所有符合条件的角色实例,按照指定字段进行排序操作。 if (!string.IsNullOrEmpty(pagination.OrderByFiled)) { var _obj JsonConvert.DeserializeAnonymousType(pagination.OrderByFil…

力扣 2351. 第一个出现两次的字母

题目 给你一个由小写英文字母组成的字符串 s ,请你找出并返回第一个出现 两次 的字母。 注意: 如果 a 的 第二次 出现比 b 的 第二次 出现在字符串中的位置更靠前,则认为字母 a 在字母 b 之前出现两次。 s 包含至少一个出现两次的字母。 …

TopK问题的必会解法

目录经典解法,创建K个大小的堆不考虑空间的暴力排序做法不考虑空间的快排partition变形减治法思想(核心:找第K大的数)空间有限放不下,海量数据的分治法经典解法,创建K个大小的堆 传统的直接建立一个K个元素的小顶堆,类…

推荐两款可以将图片无损放大的在线工具

文章目录一、waifu2x网站预览传送地址二、BigJPG网站预览传送地址好不容易找到合适的图片素材但尺寸太小?那这里的工具正好适合你,能把你的小图放大几倍都不模糊。 一、waifu2x 本程序使用卷积神经网络对动漫风格的图片进行放大操作(支持照…

再聊一下那 SQLSERVER 行不能跨页的事

一:背景 1. 讲故事 上一篇写完了之后,马上就有朋友留言对记录行的 8060byte 限制的疑惑,因为他的表记录存储了大量的文章,存储文章的字段类型用的是 nvarchar(max),长度很显然是超过 8060byte 的,请问这个…

win10搭建 IIS 服务器

第一步: 打开程序和功能 找到 Internet 这个 勾选web管理工具和万维网服务 第二步: 在本地电脑创建一个文件夹(不要有中文空格等特殊字符) index.html 是默认访问的网址 第三步 关联访问的链接 选择本地物理路径 访问测试 第四步 修改绑定端口 第五步 修改防火墙 …

Linux | 文件操作的系统调用 open() read() write()

1. 基本含义辨析 文件操作的系统调用 open read write close (系统调用:实现在内核中【用户态->内核态】—“陷入内核”) man: 1 命令 2 系统调用 3 库函数 C操作文件的库函数 fopen fread fwrite fclose (fo…

一个有意思的图片鼠标切换

做淘宝活动页面的时候,用到最多的就是锚点,一个图片标签,然后不断地在上面画热区。不过我想问的是有多少人研究过,用矩形画热点,四个坐标值各自表示的含义,还有它和background-position有什么相同或相似的地…

JavaWeb:RequestResponse的概述

1,Request和Response的概述 Request是请求对象,Response是响应对象。 这两个对象在我们使用Servlet的时候有看到: 此时,我们就需要思考一个问题request和response这两个参数的作用是什么? request:获取请…

RapidUp: Multi-Domain Permutation Protocol for Lookup Tables学习笔记

1. 引言 前序博客有: PLOOKUPPLOOKUP代码解析Efficient polynomial commitment schemes for multiple points and polynomials学习笔记PLONK PLOOKUPPlonKup: Reconciling PlonK with plookupPLONK: permutations over lagrange-bases for oecumenical nonintera…

2022年就要过去了,我的这份成绩单请您查收……

喜迎元旦岁月不居,时节如流年关交迭在即在2022行将尾声的此时想静静地坐下片刻和关注了云和恩墨这么久的老朋友们细数一遍这光阴里的纷纷呈呈这一年,充满了挑战与艰辛但所有努力和守望终有结果收成这一年,我们全心投入产品研发收获了更多的荣…

【隔离器使用说明】光隔、磁隔、容隔三兄弟介绍

文章目录前言一、三种常用隔离技术1. 光隔离2. 变压器隔离/磁隔3. 电容隔离二、隔离器重要指标1. 隔离电压值2. 爬电距离3. 共模瞬变抗扰度CMTI三、隔离器性能对比总结前言 本文简单介绍常用隔离器的类型和特点,是根据网络知识整理出来的 有错误的话请一定评论留言…

谈谈SpringBoot

1. Spring Boot 简介 简化Spring应用开发的一个框架; 整个Spring技术栈的一个大整合; J2EE开发的一站式解决方案; 2. HelloWorld 功能:浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串&a…

UE5笔记【十五】漂流者游戏制作【二】雕刻一个峡谷+增加水体

雕刻峡谷 我们希望角色从一个峡谷中开始。 用上一节中,我们配置的Auto图层,雕刻两条山脉,从而雕刻出一条峡谷。然后切换到选择模式下。我们找到PlayStart,然后将其移动到峡谷中, 然后按F切换到角色位置,调…

【C++基础】09:STL(一)

STL(一) OVERVIEWSTL(一)一、STL初识1.STL六大组件:2.容器&迭代器:二、STLGroup11.string容器:(1)基本概念:(2)string构造函数&am…