江科大睡眠,停止,待机模式hal库实现

修改主频我们直接在cubeMx上面修改就行了,很方便

睡眠,停止,待机模式是通过对电源的控制来进行的,相关代码在PWR文件里面

SEV(Send Event)

void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
void HAL_PWR_EnterSTANDBYMode(void)

当调用HAL_PWR_EnableSleepOnExit()后,处理器在中断服务程序结束返回时,会自动进入睡眠模式,除非有其他中断发生或者手动禁止该功能。

参数Regulator为调节器,PWR_MAINREGULATOR_ON主调节器,PWR_LOWPOWERREGULATOR_ON低功耗调节器

进入睡眠模式后的程序下载

按住复位键不松手,点击下载然后松手

我们把进入睡眠模式的代码写入主循环中,能一直观察到running,也就是没有成功进入睡眠模式,这是因为hal库的底层代码,systick会每隔一段时间刷新并触发一次中断,这个中断会使我们退出睡眠模式。

所以我们得在进入睡眠模式前面关闭tick时钟,在从睡眠模式恢复的时候再开启tick时钟

hal库睡眠模式串口收发

uint8_t RxData;
uint8_t Serial_RxFlag;
uint8_t Serial_GetRxFlag(void)
{if (Serial_RxFlag == 1)			//如果标志位为1{Serial_RxFlag = 0;return 1;					//则返回1,并自动清零标志位}return 0;						//如果标志位为0,则返回0
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();OLED_Init();OLED_ShowString(1, 1, "RxData:");HAL_UART_Receive_IT(&huart1,&RxData,1);while (1){if (Serial_GetRxFlag() == 1)			//检查串口接收数据的标志位{Serial_SendByte(RxData);			//串口将收到的数据回传回去,用于测试,hal库我们使用的是中断接收,所以就不需要和江科大一样把变量先读取再发送,直接发送就行了OLED_ShowHexNum(1, 8, RxData, 2);	//显示串口接收的数据}OLED_ShowString(2, 1, "Running");		//OLED闪烁Running,指示当前主循环正在运行HAL_Delay(100);OLED_ShowString(2, 1, "       ");HAL_Delay(100);HAL_SuspendTick();HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);HAL_ResumeTick();  }
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart == &huart1){Serial_RxFlag = 1;HAL_UART_Receive_IT(&huart1,&RxData,1);}
}

hal库停止模式红外对射接收器计次

while (1){/* USER CODE END WHILE */OLED_ShowNum(1, 7, CountSensor_Get(), 5);			//OLED不断刷新显示CountSensor_Get的返回值OLED_ShowString(2, 1, "Running");					//OLED闪烁Running,指示当前主循环正在运行HAL_Delay(100);OLED_ShowString(2, 1, "       ");HAL_Delay(100);/* USER CODE BEGIN 3 */HAL_SuspendTick();HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);HAL_ResumeTick();SystemClock_Config();}

停止模式结束后得重新对系统的时钟进行配置,所以我们在停止模式的后面加上cubeMx给我们生成的时钟配置函数即可。

hal库待机模式实时时钟

RTC_ReadTimeCounter()是hal库的获取时间戳的函数,这个函数在rtc文件里面是静态的,要获取时间戳的话得把他的前缀static删掉,并在.h文件里面进行声明。

标准库的闹钟设置是直接通过时间戳来设置的,而hal库的需要定义一个时间结构体作为闹钟结构体的成员,再初始化闹钟,对于相差10s的闹钟这类应用很差,不如标准库,但是对于定时时钟的闹钟效果比标准库的更直白。

闹钟配置函数

HAL_StatusTypeDef RTC_SetAlarmTenSecondsLater(RTC_HandleTypeDef *hrtc)
{RTC_TimeTypeDef sTime = {0};RTC_AlarmTypeDef sAlarm = {0};HAL_StatusTypeDef status = HAL_ERROR;/* 检查参数 */if (hrtc == NULL){return HAL_ERROR;}/* 获取当前时间 */if (HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK){return HAL_ERROR;}/* 计算十秒后的时间 */sTime.Seconds += 10;/* 处理秒数进位 */if (sTime.Seconds >= 60){sTime.Seconds -= 60;sTime.Minutes++;if (sTime.Minutes >= 60){sTime.Minutes -= 60;sTime.Hours++;if (sTime.Hours >= 24){sTime.Hours -= 24;/* 注意:这里没有处理日期进位,因为RTC_DateTypeDef未获取 */}}}/* 配置闹钟结构体 */sAlarm.AlarmTime = sTime;sAlarm.Alarm = 0x00;//闹钟成员编号,单个闹钟无用/* 设置闹钟 */status = HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN);/* 配置闹钟中断 (可选,如需要中断处理) */if (status == HAL_OK){HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);}return status;
}

相比于标准库的直接写入时间戳,hal库的这类闹钟配置比较复杂

  RTC_DateTypeDef GetData;  //获取日期结构体RTC_TimeTypeDef GetTime;   //获取时间结构体HAL_StatusTypeDef RTC_SetAlarmTenSecondsLater(RTC_HandleTypeDef *hrtc);
uint32_t Alarm;
int main(void)
{HAL_Init();SystemClock_Config();OLED_Init();MX_GPIO_Init();MX_RTC_Init();/*显示静态字符串*/OLED_ShowString(1, 1, "CNT :");OLED_ShowString(2, 1, "ALR :");OLED_ShowString(3, 1, "ALRF:");HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//wake up标志位得手动清除,不然会一直存在导致程序一直处于唤醒Alarm = RTC_ReadTimeCounter(&hrtc) + 10;			//闹钟为唤醒后当前时间的后10sOLED_ShowNum(2, 6, Alarm, 10);					//显示闹钟值RTC_SetAlarmTenSecondsLater(&hrtc);while (1){OLED_ShowNum(1, 6, RTC_ReadTimeCounter(&hrtc), 10);	//显示32位的秒计数器OLED_ShowNum(3, 6, __HAL_RTC_ALARM_EXTI_GET_FLAG(), 1);		//显示闹钟标志位OLED_ShowString(4, 1, "Running");			//OLED闪烁Running,指示当前主循环正在运行HAL_Delay(100);OLED_ShowString(4, 1, "       ");HAL_Delay(100);OLED_ShowString(4, 9, "STANDBY");			//OLED闪烁STANDBY,指示即将进入待机模式HAL_Delay(1000);OLED_ShowString(4, 9, "       ");HAL_Delay(100);OLED_Clear();								//OLED清屏,模拟关闭外部所有的耗电设备,以达到极度省电HAL_SuspendTick();HAL_PWR_EnterSTANDBYMode();     //STM32进入停止模式,并等待指定的唤醒事件(WKUP上升沿或RTC闹钟)HAL_ResumeTick();}
}

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

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

相关文章

【黄金评论】美元走强压制金价:基于NLP政策因子与ARIMA-GARCH的联动效应解析

一、基本面:多因子模型解析黄金承压逻辑 1. 政策冲击因子驱动美元强势 通过NLP模型对关税政策文本进行情感分析,构建政策不确定性指数(PUI)达89.3,触发美元避险需求溢价。DSGE模型模拟显示,钢铁关税上调至…

蓝桥云课ROS一键配置teb教程更新-250604

一键配置 echo "250604已经更新不动了"git clone https://gitcode.com/ZhangRelay1/donut.gitsudo apt-key add ~/donut/ros.keysudo apt updateecho "Upgrade Mission Completed."echo "Teb Mission Begins."sudo apt install ros-kinetic-sta…

OD 算法题 B卷【服务启动】

文章目录 服务启动 服务启动 有若干连续编号的服务(编号从0开始),服务间有依赖关系,启动一个指定的服务,请判断该服务是否可以成功启动,并输出依赖的前置服务编号;依赖关系是可以传递的&#x…

StarRocks与Apache Iceberg:构建高效湖仓一体的实时分析平台

## 引言:数据湖的挑战与演进 在数据驱动的时代,企业数据湖需要同时满足海量存储、高性能查询、多引擎协作和实时更新等复杂需求。传统基于 Hive 的数据湖方案面临元数据管理低效、缺乏 ACID 事务支持、查询性能瓶颈等问题。在此背景下,**Sta…

Kafka 单机部署启动教程(适用于 Spark + Hadoop 环境)

🧭 Kafka 单机部署启动教程(适用于 Spark Hadoop 环境) 📦 一、Kafka 版本选择 推荐使用 Kafka 2.13-2.8.1(Scala 2.13,稳定适配 Spark 3.1.2 和 Hadoop 3.1.1) 下载地址(Apache 官…

C语言数组初始化方法大全(附带实例)

在 C语言中,数组用于存储相同类型的多个元素。数组的初始化是一个重要的概念,它允许我们在声明数组的同时为其赋初值。 这篇文章,我将为大家详细介绍 C语言中初始化数组的多种方法,以及一些需要注意的细节。 数组初始化的基本语…

RAMSUN分享全新超值型MM32F0050系列MCU

凭借全国产化的供应链优势和可靠的国产高端工艺制程,灵动微再次推出全新超值型MM32F0050系列微控制器单元(MCU),将超值型MCU推向新的高度。 MM32F0050系列MCU配备了72MHz的Arm Cortex-M0内核,提供64KB的Flash存储和8K…

CMS32M65xx/67xx系列CoreMark跑分测试

CMS32M65xx/67xx系列CoreMark跑分测试 1、参考资料准备 1.1、STM32官方跑分链接 1.2、官网链接 官方移植文档,如下所示,点击红框处-移植文档: A new whitepaper and video explain how to port CoreMark-Pro to bare-metal 1.3、测试软件git下载链接 …

LeetCode 139. 单词拆分(Word Break) - 动态规划深度解析

文章目录 问题描述动态规划解法解法核心思路完整代码实现关键代码解析1. 数据结构初始化2. 动态规划数组3. 核心循环逻辑4. 子串区间理解(关键)示例演算复杂度分析算法优化点总结本文详细解析LeetCode 139题"单词拆分"的动态规划解法,涵盖核心思路、代码实现、区间…

获客方式有哪些拓展方向?

品牌在面临增长瓶颈时,如何拓展获客方式会是一个首要考虑的问题。有些时候企业会将获客渠道想得很复杂,其实仔细数下来,我们可以拓展的方向仍旧是根据渠道来溯源,因此相对固定。 一、跟随流行趋势 在数字营销领域,紧跟…

bug:undefined is not iterable (cannot read property Symbol(Symbol.iterator))

1.如图 2.分析 关键报错提示: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) 直译: undefined是不可迭代的(不能读取属性Symbol(Symbol.iterator)) 理解: 有一个值、不存在&#x…

【笔记】PyCharm 使用问题反馈与官方进展速览

#工作记录 https://youtrack.jetbrains.com/issue/IJPL-190308 【笔记】记一次PyCharm的问题反馈_the polyglot context is using an implementation th-CSDN博客 【笔记】与PyCharm官方沟通解决开发环境问题-CSDN博客 与 JetBrains 官方沟通记录(PyCharm 相关问题…

VSCode 工作区配置文件通用模板(CMake + Ninja + MinGW/GCC 编译器 的 C++ 或 Qt 项目)

下面是一个通用模板,适用于大多数使用 VSCode CMake Ninja MinGW/GCC 编译器 的 C 或 Qt 项目。你可以将这个 .vscode 文件夹复制到你的项目根目录下,稍作路径调整即可使用。 📁 .vscode/ 目录结构(通用模板) .vs…

栈-20.有效的括号-力扣(LeetCode)

一、题目解析 对于这个字符串需要左右括号匹配,并且是以正确的顺序 二、算法原理 解法1.图栈 解法2.用else if代替图栈 正常做法:对于三种左括号直接进栈((,[,{进栈),然后判断与下一个括号是否匹配,匹配则出栈,不匹…

将音频数据累积到缓冲区,达到阈值时触发处理

实现了音频处理中的 AEC(声学回声消除)和 AES(音频增强)功能,其核心功能是: 数据缓冲管理:将输入的麦克风和扬声器音频数据块累积到缓冲区中块处理机制:当缓冲区填满预设大小&#…

fastadmin+workman环境搭建

一、出现错误 从git拉取到本地在配置网址登录后出现 unserialize(): Error at offset 0 of 17039 bytes 参考:https://blog.csdn.net/yqwwj001/article/details/88688675 找到 \thinkphp\library\think\cache\driver\Flie.php 中的 $content substr($content, …

若依+vue2实现模拟登录

1、背景 第三方通过链接访问若依项目&#xff0c;该链接通过携带唯一标识符&#xff1a;phone&#xff08;手机号&#xff09;&#xff0c;项目通过手机号查询本项目数据库人员信息实现模拟登录。 2、实现 2.1. 前端实现 2.1.1 创建专用模拟登录页面PhoneLogin.vue <te…

【2025】使用docker compose一键部署项目到服务器(4)

目录&#x1f4bb; 前言一、部署准备二、本地idea配置docker和docker compose执行器三、编写docker-compose.yml文件四、执行启动 前言 该篇文章主要是使用idea通过docker-compose.yml构建容器集合并且进行统一管理更新 该专栏主要为介绍通过docker compose实现容器编排部署 &…

Linux Windows之wsl安装使用简介

参考资料 如何使用 WSL 在 Windows 上安装 Linuxwindows11 安装WSL2全流程旧版 WSL 的手动安装步骤 目录 一. 前期准备1.1 确认windows的版本1.2 开启Linux子系统的支持1.2.1 图形化方式1.2.2 命令行方式 1.3 安装wsl软件1.4 安装Linux分发版 二. 基本配置2.1 Windows Termina…

matlab模糊控制实现路径规划

路径规划是机器人和自动驾驶系统中的重要问题之一&#xff0c;它涉及确定如何在给定环境中找到最优路径以达到特定目标。模糊控制是一种有效的控制方法&#xff0c;可以应用于路径规划问题。 路径规划算法的目标是在避免障碍物的情况下&#xff0c;找到机器人或车辆从起点到终…