细说STM32F407单片机RTC的备份寄存器原理及使用方法

目录

一、备份寄存器的功能

二、示例功能

三、项目设置

1、晶振、DEBUG、CodeGenerator、USART6

2、RTC

3、NVIC 

4、GPIO 及KEYLED

四、软件设计

1、main.h

2、main.c

3、rtc.c

4、keyled.c、keyled.h

五、运行调试


        本实例旨在介绍备份寄存器的作用。本实例继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。本实例将引用本文作者写的其他文章作为参考文献。

        参考项目:细说STM32F407单片机RTC的基本原理及闹钟和周期唤醒功能的使用方法-CSDN博客  https://wenchm.blog.csdn.net/article/details/145575366

一、备份寄存器的功能

        STM32F407的RTC有20个32位的备份寄存器,寄存器名称为RTC_BKP0R~RTC_BKP19R。这些备份寄存器由备用电源VBAT供电,在系统复位或主电源关闭时,只要VBAT有电,备份寄存器的内容就不会丢失。所以,备份寄存器可以用来存储一些用户数据

        文件stm32f4xx_hal_rtc_ex.h中有读写备份寄存器的功能函数,其原型定义如下:

uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc,uint32_t BackupReg);
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc,uint32_t BackupReg,uint32_t Data);

        其中,参数BackupReg是备份寄存器编号,文stm32f4xx_hal_rtc_ex.h定义了20个备份寄存器编号的宏,定义如下:

#define RTC_BKP_DR0		0x00000000U
#define RTC_BKP_DR1		0x00000001U
/*省略了中间的定义代码*/
#define RTC_BKP_DR18	0x00000012U
#define RTC_BKP_DR19	0x00000013U

        RTC也可以由VBAT供电,在系统复位或主电源关闭时,RTC的日历不受影响。但是在参考项目,因为在系统复位时调用了RTC初始化函数MX_RTC_Init(),而这个函数总是设置RTC的日期和时间,所以复位后,RTC的日期时间又从CubeMX里设置的初始日期时间开始了。

        可以使用备份寄存器对参考项目进行修改,使得系统在复位时不再自动设置RTC的初始日期时间,而是由备份寄存器RTC_BKP_DR0的内容决定,而且可以把RTC当前时间保存到备份寄存器。

二、示例功能

        本实例,将设计一个示例,演示备份寄存器的使用。示例具有如下的功能和操作流程。

  • 在RTC初始化函数MX_RTC_Init()中增加代码,读取备份寄存器RTC_BKP_DR0的内容,如果值为0,就设置RTC为初始时间和日期,如果值为1,就不设置RTC的日期和时间。
  • 在程序运行时,可以修改保存到备份寄存器RTC_BKP_DR0的值,可以保存0或1。
  • 将RTC当前时间的时、分、秒数据保存到RTC_BKP_DR2到RTC_BKP_DR4的3个寄存器里。RTC_BKP_DR1里的值为1时,表示保存了RTC时间。
  • 读取备份寄存器RTC_BKP_DR0到RTC_BKP_DR4的内容,显示到串口助手上。
  • 使用RTC周期唤醒中断,唤醒中断周期1s,在唤醒中断里读取时间后在串口助手上显示。本示例还用到4个按键和2个LED,所以继续引用作者发布的其它参考项目中的KEYLED文件中的程序文件。
  • 菜单设计:
[S2]KeyUp   = Reset RTC time on startup.    //按下S2键,用初始时间重置RTC
[S3]KeyDown = Read BKUP registers.          //按下S3键,读取备份寄存器
[S4]KeyLeft = Save current time to BKUP.    //按下S4键,把当前时间保存到RTC备份寄存器
[S5]KeyRight= Change RTC time from BKUP.    //按下S5键,用备份寄存器存储的时间重置RTC时间

三、项目设置

1、晶振、DEBUG、CodeGenerator、USART6

        与参考文章相同。 

2、RTC

        在RTC的模式设置中,启用时钟源和日历,设置WakeUp模式为Internal WakeUp。在参数设置部分,设置数据格式为Binary data format,设置唤醒时钟为1Hz信号,唤醒周期数为0,这样就会每秒产生一次唤醒中断。

3、NVIC 

        在NVIC中开启周期唤醒中断,设置RTC抢占优先级为1。

4、GPIO 及KEYLED

        4个按键和2个LED。引用文件夹KEYLED的方法请参考本文作者发布的其它文章。

程序标签

板上名称

引脚名称

引脚功能

GPIO模式

默认电平

上拉或下拉

LED1

D1

PA6

GPIO_Output

推挽输出

High

上拉

LED2

D2

PA4

GPIO_Output

推挽输出

High

上拉

KeyRight

S5

PF6

GPIO_Input

输入

上拉

KeyDown

S3

PD3

GPIO_Input

输入

上拉

KeyLeft

S4

PF7

GPIO_Input

输入

上拉

KeyUp

S2

PA0

GPIO Input

输入

上拉

 

四、软件设计

1、main.h

/* USER CODE BEGIN Private defines */
void RTC_ToggleReset();
void RTC_SaveToBKUP();
void RTC_LoadFromBKUP();
void RTC_ReadBKUP();
/* USER CODE END Private defines */

2、main.c

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
RTC_TimeTypeDef sTime;		//RTC读取时间和日期的结果数据
RTC_DateTypeDef sDate;uint8_t RTC_isReading=0;	//RTC是否正在读日期时间数据
/* USER CODE END PV */
/* USER CODE BEGIN 2 */__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); //禁止RTC周期唤醒printf("Demo11_2_RTC_Backup:Using Backup Registers.\r\n");uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);	//读取备份寄存DR0printf("Reset RTC time on startup: ");if ((iniRTC & 0x01)==0)printf("Yes.\r\n");elseprintf("No.\r\n");/* USER CODE END 2 */
 /* Infinite loop *//* USER CODE BEGIN WHILE *///显示菜单,也可以放在USER CODE BEGIN 2里printf("[S2]KeyUp   = Reset RTC time on startup(LED2_ON).\r\n");printf("[S3]KeyDown = Read BKUP registers.\r\n");printf("[S4]KeyLeft = Save current time to BKUP.\r\n");printf("[S5]KeyRight= Change RTC time from BKUP.\r\n\r\n");__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc);	//重启RTC周期唤醒while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);switch(curKey){case KEY_UP:		//[S2]KeyUp,改变保存到备份寄存器DR0的数值0 or 1RTC_ToggleReset();break;case KEY_DOWN:	//[S3]KeyDown,读取5个备份寄存器的数据并显示RTC_ReadBKUP();case KEY_LEFT:	//[S4]KeyLeft,将RTC当前时间保存到备份寄存器RTC_SaveToBKUP();break;case KEY_RIGHT:	//[S5]KeyRight,从备份寄存器读取时间,改变RTC时间RTC_LoadFromBKUP();break;default:break;}HAL_Delay(300);	//消抖}/* USER CODE END 3 */

        main()函数里在完成了外设初始化之后,执行__HAL_RTC_WAKEUPTIMER_DISABLE (&hrtc),禁止了RTC周期唤醒单元。在进入while死循环之前,再开启RTC的周期唤醒单元。

        调用函数HAL_RTCEx_BKUPRead()读取备份寄存器RTC_BKP_DR0的内容,如果寄存器的值为0就会在MX_RTC_Init()里用CubeMX设置的初始日期和时间设置RTC的日期时间;如果寄存器的值不为0在MX_RTC_Init()里就不会设置RTC的日期和时间。后一种情况下,在按复位键[S6]使系统复位时,RTC仍然保持连续的时间,因为RTC工作在备份域,不会在系统复位时复位。

        然后,在串口助手上显示了一个模拟菜单。

        在while循环里读取按键输入,用4个按键模拟菜单项的选择,按下某个按键后就执行与菜单项对应的功能。按键的响应代码封装为4个函数。

/* USER CODE BEGIN 4 */
//周期唤醒中断回调函数
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{LED1_Toggle();RTC_isReading = 1;		//RTC正在读取数据,该变量的作用类似于RTOS中的二值信号量if (HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK){//调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新日期和时间HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BIN);RTC_isReading = 0;	//RTC结束了读取数据//显示时间hh:mm:sschar str[40];sprintf(str,"RTC Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s\r\n",str);}
}/* 翻转保存备份寄存器RTC_BKP_DR0的值 */
void RTC_ToggleReset()	//S2
{uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);iniRTC = !iniRTC;if ((iniRTC & 0x01)==0){ //存储值为0时,用CubeMX中的值复位日期时间printf("Reset RTC time on startup.\r\n");LED2_ON();}else{printf("Not reset RTC time on startup.\r\n");LED2_OFF();}//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);		//取消写保护HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0, iniRTC);	//写入备份寄存器DR0//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);		//开启写保护
}/* RTC时间保存到备份寄存器 */
void RTC_SaveToBKUP()	//S4
{while (RTC_isReading)	//如果RTC的WakeUp中断里正在读取数据,就等待其读取完HAL_Delay(1);//__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);				//取消写保护HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, 0x01);			//0x01=保存了时间的标志HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, sTime.Hours);	//使用全局变量sTime,不再读取当前时间HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, sTime.Minutes);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, sTime.Seconds);//__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);				//开启写保护char timeStr[30];sprintf(timeStr,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);	//转换为字符串,自动添加"\0"printf("Current time %s is saved in BKUP.\r\n",timeStr);
}/* 用保存的时间设置为RTC时间 */
void RTC_LoadFromBKUP()	//S5
{uint32_t isTimeSaved = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);	//读取备份寄存DR1if (isTimeSaved){RTC_TimeTypeDef time;time.Hours = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);time.Minutes = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);time.Seconds = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;		//这两个参数还是有用的,如果不设置这2个参数,设置的小时数会自动减1time.StoreOperation = RTC_STOREOPERATION_SET;//HAL_Delay(10);		//必须加这个延时,否则设置的时间会错乱while(RTC_isReading)	//如果RTC正在WakeUp中断里读取数据,就等待其读完HAL_Delay(1);/*函数HAL_RTC_SetTime()内部在修改RTC的寄存器之前,会调用 __HAL_RTC_WRITEPROTECTION_DISABLE()取消写保护,写完之后,会调用 __HAL_RTC_WRITEPROTECTION_ENABLE() 重新开启写保护 */if (HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN) == HAL_OK)printf("Load and set BKUP time, success.\r\n");elseprintf("Load and set BKUP time, failure.\r\n");}elseprintf("No BKUP time is saved.\r\n");
}/* 读取5个备份寄存器内容并显示 */
void RTC_ReadBKUP()	//S3
{uint32_t regValue;char regStr[40];regValue = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0);	//0=系统复位时复位RTC时间sprintf(regStr,"Reset RTC ,BKP_DR0= %lu",regValue);	//转换为字符串,自动添加"\0"printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);	//1=有时间数值sprintf(regStr,"Time is saved,BKP_DR1= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);	//Hoursprintf(regStr,"Saved time(Hour) ,BKP_DR2= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);	//Minutesprintf(regStr,"Saved time(Min) , BKP_DR3= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);	//Secondsprintf(regStr,"Saved time(Sec) , BKP_DR4= %lu",regValue);printf(" %s\r\n",regStr);
}//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

        回调函数HAL_RTCEx_WakeUpTimerEventCallback()处理RTC周期唤醒中断。

        其余的4个函数,是对4个菜单项的响应代码的封装。

3、rtc.c

/* USER CODE BEGIN Check_RTC_BKUP */uint32_t iniRTC = HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0);	//读取备份寄存DR0if ((iniRTC & 0x01))  //非零,无需初始化RTC日期时间{if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,0,RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)Error_Handler();return;  //提前退出函数}/* USER CODE END Check_RTC_BKUP */

        沙箱中添加的代码就是用函数HAL_RTCEx_BKUPRead()读取备份寄存器RTC_BKP_DR0的内容,如果寄存器的值不为0,就在执行完HAL_RTCEx_SetWakeUpTimer_IT()设置和启动周期唤醒后,退出函数;如果寄存器的值为0,就继续执行函数内后面的代码。

        这样,就在函数MX_RTC_Init()中加入了用户功能代码,使得在系统复位时,RTC不必设置初始日期和时间

4、keyled.c、keyled.h

        引用KEYLED文件夹下的 keyled.c、keyled.h,使用方法请参考本文作者发布的其他文章。

五、运行调试

        首次下载,或按S6键复位,显示系统菜单。重要的信息是显示当前从哪里重置RTC时间的信息。如果YES(LED2亮)则从RTC初始化值(15:30:0)重置RTC时间,否则不是;

        按S2键切换从哪里重置RTC时间。比如,下图,每次按下S6复位键,系统都从RTC初始化值重置时间,否则不重置时间,即当LED2灯不亮(DR0=1)时,按下复位键S6,不改变RTC时间,连续显示RTC时间。

 

         按S4键,存储当前时间到备份寄存器;按S3键,读取备份存储器内容并保存当前最新值到备份寄存器;按S5键,用备份寄存器内容重置RTC时间;

 

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

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

相关文章

建筑行业安全技能竞赛流程方案

一、比赛时间&#xff1a; 6月23日8&#xff1a;30分准时到场&#xff1b;9&#xff1a;00&#xff0d;10&#xff1a;00理论考试&#xff1b;10&#xff1a;10-12:00现场隐患答疑&#xff1b;12:00-13&#xff1a;30午餐&#xff1b;下午13&#xff1a;30-15&#xff1a;30现场…

解锁机器学习核心算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…

JAVA生产环境(IDEA)排查死锁

使用 IntelliJ IDEA 排查死锁 IntelliJ IDEA 提供了强大的工具来帮助开发者排查死锁问题。以下是具体的排查步骤&#xff1a; 1. 编写并运行代码 首先&#xff0c;我们编写一个可能导致死锁的示例代码&#xff1a; public class DeadlockExample {private static final Obj…

解决DeepSeek服务器繁忙问题

目录 解决DeepSeek服务器繁忙问题 一、用户端即时优化方案 二、高级技术方案 三、替代方案与平替工具&#xff08;最推荐简单好用&#xff09; 四、系统层建议与官方动态 用加速器本地部署DeepSeek 使用加速器本地部署DeepSeek的完整指南 一、核心原理与工具选择 二、…

机器学习 - 大数定律、可能近似正确学习理论

一、大数定律&#xff1a; 大数定律是概率论中的一个基本定理&#xff0c;其核心思想是&#xff1a;当独立重复的随机试验次数足够大时&#xff0c;样本的平均值会趋近于该随机变量的期望值。下面从直观和数学两个角度来说明这一概念&#xff1a; 1. 直观理解 重复试验的稳定…

【触想智能】工业显示器和普通显示器的区别以及工业显示器的主要应用领域分析

在现代工业中&#xff0c;工业显示器被广泛应用于各种场景&#xff0c;从监控系统到生产控制&#xff0c;它们在实时数据显示、操作界面和信息传递方面发挥着重要作用。与普通显示器相比&#xff0c;工业显示器在耐用性、可靠性和适应特殊环境的能力上有着显著的差异。 触想工业…

PyCharm2024使用Python3.12在Debug时,F8步进时如同死机状态

在使用时PyCharm2024&#xff0b;Python3.12&#xff0c;在程序进行调试时&#xff0c;按F8步进时如同死机状态。 1、相同的程序在PyCharm2023&#xff0b;Python3.9时是没有问题的&#xff0c;因此决定重装PyCharm2023&#xff0b;Python3.9&#xff0c;进行调试——调试OK。 …

LLaMA-Factory DeepSeek-R1 模型 微调基础教程

LLaMA-Factory 模型 微调基础教程 LLaMA-FactoryLLaMA-Factory 下载 AnacondaAnaconda 环境创建软硬件依赖 详情LLaMA-Factory 依赖安装CUDA 安装量化 BitsAndBytes 安装可视化微调启动 数据集准备所需工具下载使用教程所需数据合并数据集预处理 DeepSeek-R1 可视化微调数据集处…

STM32 如何使用DMA和获取ADC

目录 背景 ‌摇杆的原理 程序 端口配置 ADC 配置 DMA配置 背景 DMA是一种计算机技术&#xff0c;允许某些硬件子系统直接访问系统内存&#xff0c;而不需要中央处理器&#xff08;CPU&#xff09;的介入&#xff0c;从而减轻CPU的负担。我们可以通过DMA来从外设&#xf…

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十六节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析&#xff08;LinkControl_0x87服务&#xff09; 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月14日 关键词&#xff1a;UDS协议、0x87服务、链路控制、ISO 14229-1:2023、ECU测试 一、服务功能概述 0x87服务…

DeepSeek与医院电子病历的深度融合路径:本地化和上云差异化分析

一、引言 1.1 研究背景与意义 在医疗信息化快速发展的当下,电子病历系统已成为医院信息管理的核心构成。电子病历(EMR)系统,是指医务人员在医疗活动过程中,使用医疗机构信息系统生成的文字、符号、图标、图形、数据、影像等数字化信息,并能实现存储、管理、传输和重现的…

Django中实现简单易用的分页工具

如何在Django中实现简单易用的分页工具&#xff1f;&#x1f4da; 嗨&#xff0c;小伙伴们&#xff01;今天我们来看看如何在 Django 中实现一个超简单的分页工具。无论你是在处理博客文章、产品列表&#xff0c;还是用户评论&#xff0c;当数据量一大时&#xff0c;分页显得尤…

【kafka系列】生产者

目录 发送流程 1. 流程逻辑分析 阶段一&#xff1a;主线程处理 阶段二&#xff1a;Sender 线程异步发送 核心设计思想 2. 流程 关键点总结 重要参数 一、核心必填参数 二、可靠性相关参数 三、性能优化参数 四、高级配置 五、安全性配置&#xff08;可选&#xff0…

Docker 入门与实战:从安装到容器管理的完整指南

&#x1f680; Docker 入门与实战&#xff1a;从安装到容器管理的完整指南 &#x1f31f; &#x1f4d6; 简介 在现代软件开发中&#xff0c;容器化技术已经成为不可或缺的一部分。而 Docker 作为容器化领域的领头羊&#xff0c;以其轻量级、高效和跨平台的特性&#xff0c;深…

MySQL 插入替换语句(replace into statement)

我们日常使用 insert into 语句向表中插入数据时&#xff0c;一定遇到过主键或唯一索引冲突的情况&#xff0c;MySQL的反应是报错并停止执行后续的语句&#xff0c;而replace into语句可以实现强制插入。 文章目录 一、replace into 语句简介1.1 基本用法1.2 使用set语句 二、注…

基于SpringBoot+Vue的智慧校园管理系统设计和实现(源码+文档+部署讲解)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 .&#x1f680; 技术架构技术栈全景 &#x1f3af; 功能模块功能矩阵表&#x1f4ca; 数据库设计核心ER关系图 &#x1f4bb; 核心…

【Three.js】JS 3D library(一个月进化史)

#春节过完了&#xff0c;该继续投入学习了~ 作为一个平面开发者&#xff0c;想要增进更多的技能&#xff0c;掌握web3D开发# Day 1 了解熟悉Three.js&#xff0c;着重基础理论 学习资源&#xff1a; 前端可视化从0-1 Day 2 写一个简易demo 搭建环境-->安装包-->创建…

moveable 一个可实现前端海报编辑器的 js 库

目录 缘由-胡扯本文实验环境通用流程1.基础移动1.1 基础代码1.1.1 data-* 解释 1.2 操作元素创建1.3 css 修饰1.4 cdn 引入1.5 js 实现元素可移动1.6 图片拖拽2.缩放3.旋转4.裁剪 懒得改文案了&#xff0c;海报编辑器换方案了&#xff0c;如果后面用别的再更。 缘由-胡扯 导火…

Apollo 9.0 速度动态规划决策算法 – path time heuristic optimizer

文章目录 1. 动态规划2. 采样3. 代价函数3.1 障碍物代价3.2 距离终点代价3.3 速度代价3.4 加速度代价3.5 jerk代价 4. 回溯 这一章将来讲解速度决策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的内容。Apollo 9.0使用动态规划算法进行速度决策&#xff0c;从类名…

【Day41 LeetCode】单调栈问题

一、单调栈问题 单调栈问题通常是在一维数组中寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。 1、每日温度 739 这题的目的是对于当天&#xff0c;找到未来温度升高的那一天&#xff0c;也就是当前元素的右边第一个比自己大的元素。所以我们需要维护一个单…