STM32中待机模式与看门狗的冲突问题

2023-10-27

最近在做刚刚入职的第一个STM32的项目,需要用到按键进入以及退出低功耗(待机模式),同时也要用到看门狗,排除进入低功耗待机模式的一些问题后加入看门狗,发现独立看门狗无法关闭,这样导致了待机模式无法进入。

首先介绍一下STM32低功耗,按功耗由高到低排列,STM32具有运行、睡眠、停止和待机四种工作模式。上电复位后 STM32 处于运行状态,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户根据实际情况选用不同的低功耗模式,三种低功耗的模式说明如下图:

一、休眠模式

最开始做低功耗考虑的是休眠模式(SLEEP),在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3核心的外设全都还照常运行,可以理解为代码停止运行了。如下代码可见,休眠模式需要关闭所有实时的内部中断,因为SLEEP模式会被所有的中断唤醒,因此在退出休眠模式之后需要重新使能被失能的中断。

void sleep(void)
{
    //printf("Start of sleep mode!\r\n");
    HAL_SuspendTick();
    HAL_TIM_Base_Stop_IT(&htim2);
    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFE);
    //printf("End of sleep mode!\r\n");
    HAL_ResumeTick();
    HAL_TIM_Base_Start_IT(&htim2);
}

SLEEP模式相对来说比较简单但是局限性也比较大,如上代码中我关闭了TIM定时器中断才得以进入休眠模式,但是我的按键的长短按的判定是TIM定时器中断来判断的,因此我关闭了TIM中断我的开关就失效了,这时候只有一个办法,加入外部中断来唤醒SLEEP,也就是说我要再加一个按键中断来唤醒,但是我只有一个开关,或者说放弃定时器用延时来做开关的长度按,这样又会丧失一些精度。最后我还是决定换个方案试试看。

二、待机模式

因为看到STOP模式也会被中断唤醒(具体STOP是怎么样的我还没研究过),所有我先绕过它开始研究待机模式,正点原子上有个例程给我看傻了,他在中断里面加了三秒的延时,通常在中断子程序中是不调用延时子程序的,这样会增加中断处理时间,如果有其它低级中断了,就会延误响应中断了。这样是非常不规范的行为,不建议大家这样做。同时我也舍不得我的TIM定时器开关,所以就先自己琢磨了一下。

待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。

它除了关闭所有的时钟,还把 1.8V 区域的电源也完全关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测 boot 条件,相当于从头开始执行程序。

void Sys_Enter_Standby(void)
{
     __HAL_RCC_APB2_FORCE_RESET(); //复位所有IO
     __HAL_RCC_PWR_CLK_ENABLE(); //使能 PWR 时钟
     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //清除 Wake_UP 标志
     HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN3); //设置 WKUP 用于唤醒
     HAL_PWR_EnterSTANDBYMode(); //进入待机模式 
}

待机模式的唤醒条件:

当一个外部复位(NRST 引脚)、IWDG 复位、WKUP 引脚上的上升沿或 RTC 闹钟事件

发生时,微控制器从待机模式退出。

因为要配合按键所以当仁不让的的选择了WKUP引脚上升沿唤醒,这样做也遇到了个新的问题:第一次进入待机模式时瞬间被唤醒了,但是再次进入待机模式却不会出现这个问题,研究了一会发现是延时的问题,我做了一个长按3s以上进入待机模式,短按30ms退出休眠的设定,那么第一次进入休眠模式时除非使用者刚刚好长按3s,不然立即会被上升沿唤醒,多1ms都不行。这样是有问题的。后面也是找到了解决办法:

  if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 0)
  {
    Sys_Enter_Standby();
  }

在main函数的While循环开始之前对WAKE_UP开关进行判定如果是低电平也就是未触发状态那么直接进入休眠模式,也就是代码烧写进去必须短按一下,退出休眠才能正常运行。让后长按进入休眠短按退出休眠在再无异常。那么休眠模式与按键的问题看起来就解决了。可以加入看门狗了,新的问题也随之而来。

最开始我加入了独立看门狗,但是大家可以看到,待机模式的唤醒条件中恰恰有IWDG复位,IWDG为什么复位?当然是因为没有喂狗,那么都待机了还拿什么喂狗。我最开始想到的是进入待机前关闭看门狗,但是通过不断百度得出结论,无法关闭,即使是待机,在感叹IWDG功能强大的同时我也开始头疼了。那么还有一个方案:RTC闹钟喂狗然后再次休眠,越想越扯了属于是,这样反复横跳对MCU长此以往必然是有损伤的,那还不如不做这个休眠。

最后发现貌似还有一个看门狗:WWDG,这个窗口看门狗看起来虽然复杂一些,但是貌似会被待机模式关闭,说干就干,这就用CUBE来一段:

#include "wwdg.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

WWDG_HandleTypeDef hwwdg;

/* WWDG init function */
void MX_WWDG_Init(void)
{

  hwwdg.Instance = WWDG;
  hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
  hwwdg.Init.Window = 0x40;
  hwwdg.Init.Counter = 0x7f;
  hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;
  if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_WWDG_MspInit(WWDG_HandleTypeDef* wwdgHandle)
{

  if(wwdgHandle->Instance==WWDG)
  {
  /* USER CODE BEGIN WWDG_MspInit 0 */

  /* USER CODE END WWDG_MspInit 0 */
    /* WWDG clock enable */
    __HAL_RCC_WWDG_CLK_ENABLE();

    /* WWDG interrupt Init */
    HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(WWDG_IRQn);
  /* USER CODE BEGIN WWDG_MspInit 1 */

  /* USER CODE END WWDG_MspInit 1 */
  }
}

同时最后用中断喂狗,简单快捷:

void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
{
    //printf("feed dog!\r\n");
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
    HAL_WWDG_Refresh(hwwdg);//更新窗口看门狗
}

对了不要忘了启用提前喂狗中断以及使能看门狗中断:

最终效果(暂时用串口助手来展示一下):

代码烧录之后的状态(默认进入了待机模式):

按下WAKE-UP,代码正常打印:

长按WAKE_UP进入休眠:

如此也算是完美(避开问题罢了)解决了看门狗与待机模式的冲突。

(嵌入式新人,可能有一些地方说的不对,欢迎指正。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32中待机模式与看门狗的冲突问题 的相关文章

  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 关注MCU 开发中的无限循环

    在 MCU 的开发过程中 我们经常会遇到需要使用无限循环的情况 例如 在前后台系统中 我们需要在一个无限循环中处理各种任务 在实时性操作系统中 我们也可能需要在一个无限循环中调度各个任务 那么 处理无限循环的语句有哪些写法呢 目前常见的有两
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • C语言环形缓冲区

    2024第一天 继续给自己加点料 导言 C语言环形缓冲区是一种常用的数据结构 它提供了一种高效的方式来存储和处理数据 本文将深入解析C语言环形缓冲区的定义 原理和应用 并提供一些实际的代码示例 一 什么是环形缓冲区 环形缓冲区 也称为循环缓
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • 20张原版Python科学速查表,数据分析不再是难题

    1 Python基础 2 Pandas基础 3 Numpy基础 4 PySpark基础 5 数组排序算法 6 scikit learn算法小抄 内容就不给大家一一自行领取哦
  • 编译UNP源码

    读UNP需要用到官方的源码 记录一下折腾的记录 源码下载地址 http www unpbook com 下载源码后 解压出文件夹unpv13e cd进入后 依次进行下面操作 configure cd lib make 这两步没有问题 出现w
  • 程序内执行shell命令自动获取局域网内所有在线IP和开放端口(Linux)

    前言 题目说的有点长 其实就是以下几件事 第一是让Shell命令可以在程序内执行 然后将执行结果传递给变量 从而可以进行后续的事务处理 第二是使用nmap命令获取当前局域网内所有在线IP和开放的端口 最后就是对nmap获得的结果进行处理 得
  • Nexus因异常重启导致OrientDB数据库变为只读的问题修复

    文章目录 环境 问题描述 问题排查 解决步骤 环境 CentOS 7 6 Nexus 3 21 2 问题描述 装有Nexus的服务机在异常故障重启后 Nexus可以正常读取和拉取jar包 但尝试上传时报错 打开Nexus服务器上的日志文件发
  • 机器学习PCA——实验报告

    机器学习实验报告 实验报告pdf可在该网址下载 一 实验目的与要求 二 实验内容与方法 2 0 PCA算法学习与回顾 2 0 1 PCA推导的优化问题 2 0 2 优化问题的解 2 0 3 算法流程 2 1 人脸数据集 2 2 实验流程图
  • Qt—QPainter基本图形绘制详解

    QPainter描述 1 QPainter 类在小部件和其他绘制设备上执行低级绘制 2 QPainter 提供了高度优化的功能来完成大多数图形GUI程序所需的工作 它可以画从简单的线条到复杂的形状 它还可以绘制对齐的文本和像素图 QPain
  • sideeffects没配置css也还在,webpack4踩坑配置之sideEffects, 打包文件中没有css文件

    最开始先来讲一下sideEffects sideEffects sideEffects意为副作用 无副作用类似纯函数的概念 接受参数并返回值 不产生其他影响 这里的副作用针对模块 如果一个模块单纯的导入导出变量那就是无副作用的 如果还修改其
  • docker从安装到部署一个项目

    一 centos安装docker 参考博客 https blog csdn net m0 47010003 article details 127775185 1 设置一下下载Docker的镜像源 设置下载的镜像源为国内的阿里云 如果不设置
  • sqlilabs第五关

    文章目录 前言 一 二次注入 二 别的方法 三 sqlmap 前言 本来这篇博客前几天就准备写 奈何因为各种原因拖到了现在 然后参加ctf又白给 不说了 都是泪 流眼泪 jpg 如有错误希望各位师傅指正 拜托 jpg 一 二次注入 本次采用
  • iOS一键生成所有图标

    记录一个iOS开发一键生成图标的网站 https icon wuruihong com
  • CUDA性能优化系列——Kmeans算法调优(二)

    本篇介绍Kmeans算法中计算新的聚类中心部分 这部分主要逻辑 根据计算出的新的分类信息 对全部数据点依次对每个类别求出所属当前类别的数据点个数与坐标和 本质上就是进行规约运算 V1 Atomic实现全局规约 由于最终生成16个聚类中心 因
  • k-均值聚类Python代码实现

    k 均值聚类的简介可以参考 http blog csdn net fengbingchun article details 79276668 这里给出两种方式的k 均值实现 code主要来自于网络 1 以下code来自于 https mub
  • TensorFlow、PyTorch分布式训练

    要在两台主机之间使用分布式训练 您可以使用一些深度学习框架提供的工具和库来实现 这里以TensorFlow为例 介绍一下如何在两台主机之间使用分布式训练 首先 您需要安装TensorFlow和CUDA等相关软件 并确保两台主机都可以访问彼此
  • 基于nvJpeg编解码图片

    NvJpeg介绍 nvJPEG库为深度学习和超大规模多媒体应用程序中常用的图像格式提供了高性能 GPU加速的JPEG解码功能 该库提供单个和批处理JPEG解码功能 可有效利用可用GPU资源实现最佳性能 以及用户管理内存分配的灵活性需要解码
  • [转]QNX系统-基于高通骁龙SA8155平台,中科创达发布智能驾驶舱3.0解决方案

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 声明 本文只用于个人学习交流 若不慎造成侵权 请及时联系我 立即予以改正 锋影 email 174176320 qq com 作为亚洲地区前
  • 百度云对象存储的图片转webp不展示图片的解决方案

    前言 百度云对象存储的图片 加上图片处理的参数后 像这种转webp格式的请求https xxxxxxxx cn xxxxxx jpg x bce process image format f webp 由于图片过大 导致请求超时了 提交了工
  • 测试用例优化和强化

    测试数据管理 1问题的提出 用例优化 2问题的提出
  • C1认证学习笔记(第二章)

    C1认证 二 web基础 语义化标签 任务目标 任务背景 常见的语义化标签 任务练习 表单标签 任务目标 任务背景 form标签 input 元素 label标签 select标签 button元素 任务练习 转义字符 任务目标 任务背景
  • Set排序

    工作中遇到 写了很久以前的写法 师兄给了很多建议 于是整理了一下 孔子曰 你知道茴香豆的茴字有几种写法吗 第一种 平常的写法 public class App public static void main String args Set
  • STM32中待机模式与看门狗的冲突问题

    最近在做刚刚入职的第一个STM32的项目 需要用到按键进入以及退出低功耗 待机模式 同时也要用到看门狗 排除进入低功耗待机模式的一些问题后加入看门狗 发现独立看门狗无法关闭 这样导致了待机模式无法进入 首先介绍一下STM32低功耗 按功耗由