修改主频睡眠模式停止模式待机模式

代码示例:

接线图:修改主频
在这里插入图片描述

接线图:睡眠模式+串口发送+接收
CH340 USB转串口模块。GND和stm32共地。RXD接PA9,TXD接PA10。
在这里插入图片描述
接线图:停止模式+对射式红外传感器计次
对射式红外传感器模块的VCC和GND接上供电。DO输出接STM32的PB14引脚。
在这里插入图片描述

接线图:待机模式+实时时钟
PA0引出一根线,目的是,可以手动把PA0接到3.3v或断开。因为PA0有个WKUP,可以唤醒待机模式,WKUP引脚上升沿有效。直接接一个线短接到3.3v,来手动产生一个上升沿,测试WKUP的效果。

在这里插入图片描述
研究system_stm32f10x.h、system_stm32f10x.c文件:

system_stm32f10x.h、system_stm32f10x.c文件是用来配置系统时钟的,也就是配置RCC时钟树。
RCC时钟树
在这里插入图片描述

在这里这个图就是RCC时钟树的全部电路,左边是四个时钟源,HSI、HSE、LSE、LSI用于提供时钟,右边就是各个外设,就是使用时钟的地方,我们用的最多的就是AHB时钟、APB1时钟、APP2时钟。另外还有一些时钟,它们的来源不是AHB和APB,比如I2S的时钟直接来源于system clock,USB的时钟直接来源于PLL。

我们主要关心的就是这个外部的8MHz晶振,它如何进行选择,如何倍频才能得到这个72MHz的SYSCLK系统主频,然后系统主频如何去分配,才能得到AHB、APB1和APB2的时钟频率,

在这里插入图片描述
#if叫做预编译,主要是用来兼容不同型号的设备 。修改主频,把宏解除注释(/*)。

当前带钥匙符号代表文件只读,解除只读的方法:打开工程文件夹或在system_stm32f10x.c右键,点打开包含的文件夹
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述
右键,属性
在这里插入图片描述
把只读的√去掉。
在这里插入图片描述
如想整个文件或整个工程文件夹都取消只读,在外面对整个文件夹操作,点击属性,把只读去掉即可。
在这里插入图片描述

总结:首先是是Systemlnit函数,进来启动HSI,之后就是各种缺省配置,最后调用SetSysClock;SetSysClock是一个分配函数,根据前面解除不同的宏定义,选择执行不同的配置函数:如SetSysClockTo72、To56、To48等。最后在SetSysClockTo72里配置函数,如配置是:选择HSE作为锁相环输入,之后锁相环进行9倍频,再选择锁相环输出,作为主频,这样主频就是72MHZ。
在这里插入图片描述

修改主频

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"int main(void)
{OLED_Init();							//OLED初始化OLED_ShowString(1, 1, "SYSCLK:");		//显示静态字符串OLED_ShowNum(1, 8, SystemCoreClock, 8);	//显示SystemCoreClock变量//SystemCoreClock的值表示当前的系统主频频率while (1){OLED_ShowString(2, 1, "Running");	//闪烁Running,指示当前主循环运行的快慢Delay_ms(500);OLED_ShowString(2, 1, "       ");Delay_ms(500);}
}

程序现象:
第一行主频频率是36M。第二行Running闪烁周期是2s。
在这里插入图片描述

睡眠模式

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"uint8_t RxData;			//定义用于接收串口数据的变量int main(void)
{OLED_Init();		//OLED初始化OLED_ShowString(1, 1, "RxData:");	//显示静态字符串Serial_Init();		//串口初始化while (1){if (Serial_GetRxFlag() == 1)			//检查串口接收数据的标志位{RxData = Serial_GetRxData();		//获取串口接收的数据Serial_SendByte(RxData);			//串口将收到的数据回传回去,用于测试OLED_ShowHexNum(1, 8, RxData, 2);	//显示串口接收的数据}OLED_ShowString(2, 1, "Running");		//OLED闪烁Running,指示当前主循环正在运行Delay_ms(100);OLED_ShowString(2, 1, "       ");Delay_ms(100);__WFI();								//执行WFI指令,CPU睡眠,并等待中断唤醒//执行WFI这时CPU会立刻睡眠,程序就停在了WFI指令这里,但是各个                                                                                    外设比如USRT还是工作状态//等到我们用串口助手发送数据时,USRT外设收到数据产生中断,唤醒CPU之后程序在暂停的地方继续运行}
}

程序现象
串口助手发送数据,每发送一个Running闪烁一次,接收区回传一次数据,说明程序在收到数据之后,可以唤醒工作一次。在不影响功能的前提下,CPU能在空闲时睡眠,节约用电。
在这里插入图片描述

停止模式

停止模式只能通过外部中断触发(唤醒),所以和停止模式相关的代码肯定得用外部中断。

在停止模式下1.8V区域的时钟关闭,CPU和外设都没有时钟了,但是外部中断的工作是不需要时钟的,这一点从代码里也可以看出来,初始化的时候,根本就没有开启EXTI时钟的参数,这也是EXTI能在时钟关闭的情况下工作的原因。

刚才讲的睡眠模式其实都只是内核的操作,睡眠模式涉及的几个寄存器也都是在内核里,跟PWR外设关系不大,所以刚才我们都没用到PWR的库函数,不过现在停止模式涉及到内核之外的电路操作,这就需要用到PWR外设了,看一下库函数。

PWR.h里常用函数

void PWR_DeInit(void);//恢复缺省配置
void PWR_BackupAccessCmd(FunctionalState NewState); // 使能后备区域的访问// 配置PVD使能电压
void PWR_PVDCmd(FunctionalState NewState);	   //使能PVD功能
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);//配置PVD的阈值电压// 使能WKUP引脚唤醒功能在待机模式下使用
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能位于PA0位置的WKUP引脚 配合待机模式使用// 进入停止模式
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);// 进入待机模式
void PWR_EnterSTANDBYMode(void);FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); //获取标志位
void PWR_ClearFlag(uint32_t PWR_FLAG); //清除标志位

main .c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"int main(void)
{/*模块初始化*/OLED_Init();			//OLED初始化CountSensor_Init();		//计数传感器初始化/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		//开启PWR的时钟//停止模式和待机模式一定要记得开启/*显示静态字符串*/OLED_ShowString(1, 1, "Count:");while (1){OLED_ShowNum(1, 7, CountSensor_Get(), 5);			//OLED不断刷新显示CountSensor_Get的返回值OLED_ShowString(2, 1, "Running");					//OLED闪烁Running,指示当前主循环正在运行Delay_ms(100);OLED_ShowString(2, 1, "       ");                   //把Running清除Delay_ms(100);PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);	//STM32进入停止模式,并等待中断唤醒SystemInit();										//唤醒后,要重新配置时钟。重新启动SHE,配置72MHZ}                                                       
}

程序现象

在空闲时,Running没有闪烁。每遮挡一次,Running闪烁一下。而复位后第一次的Running闪烁很快,是正常的时间,而遮挡之后,Running闪烁变慢。
退出停止模式时,HSI被选为系统时钟,也就是在我们首次复位后,SystemInit函数里配置的是HSE*9倍频的72M主频。 所以复位后第一次Running闪烁很快,而之后进入停止模式,再退出时默认时钟就变成HSI了,HSI是8M,所以唤醒之后的程序运行就会明显变慢。

在这里插入图片描述

待机模式

主要任务是,第一,设置RTC时钟;第二,进入待机模式;第三,使用闹钟信号,唤醒待机模式。

代码:
main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化MyRTC_Init();		//RTC初始化/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		//开启PWR的时钟//停止模式和待机模式一定要记得开启  虽然MyRTC_Init里开启了,多次开启无所谓,防止其他没调用MyRTC_Init的场景   但时钟没开启外设就不会工作。/*显示静态字符串*/OLED_ShowString(1, 1, "CNT :");              //显示秒计数器OLED_ShowString(2, 1, "ALR :");              //显示闹钟值OLED_ShowString(3, 1, "ALRF:");              //闹钟标志位/*使能WKUP引脚*/PWR_WakeUpPinCmd(ENABLE);						//使能位于PA0的WKUP引脚,WKUP引脚上升沿唤醒待机模式/*设定闹钟*/uint32_t Alarm = RTC_GetCounter() + 10;			//闹钟为唤醒后当前时间的后10sRTC_SetAlarm(Alarm);							//写入闹钟值到RTC的ALR寄存器 ,这个寄存器只写不可读,所以使用变量Alarm显示到OLED上OLED_ShowNum(2, 6, Alarm, 10);					//显示闹钟值while (1){OLED_ShowNum(1, 6, RTC_GetCounter(), 10);	//显示32位的秒计数器OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1);		//显示闹钟标志位,显示长度为1OLED_ShowString(4, 1, "Running");			//OLED闪烁Running,指示当前主循环正在运行Delay_ms(100);OLED_ShowString(4, 1, "       ");           //Running清除Delay_ms(100);OLED_ShowString(4, 9, "STANDBY");			//OLED闪烁STANDBY,指示即将进入待机模式Delay_ms(1000);OLED_ShowString(4, 9, "       ");Delay_ms(100);OLED_Clear();								//OLED清屏,模拟关闭外部所有的耗电设备,以达到极度省电PWR_EnterSTANDBYMode();						//STM32进入停止模式,并等待指定的唤醒事件(WKUP上升沿或RTC闹钟)/*待机模式唤醒后,程序会重头开始运行*/}   //待机模式之后的代码执行不到,下次继续从头开始 在程序刚开始的时候自动调用SystemInit初始化时钟,所以待机模式我们就不用像停止模式那样,自己调用SystemInit了//并且这个while循环,实际上也只有执行一遍的机会,把这个while循环去掉也是可以的
}

程序现象:

复位后,Running闪烁一次,进入待机,当然CNT也不会进行刷新了,然后需等一下,闹钟触发,待机模式唤醒 ,CNT和闹钟值刷新一下,Running闪烁一次。并且,每次唤醒后,闹钟值都会重新设定,通过这一现象,确定待机模式唤醒后,程序是从头开始执行。stm32进入待机模式之前,要把外部接的模块全部关掉。

在这里插入图片描述
最开始显示信息,进入待机,OLED清屏,等待一会,闹钟触发之后,唤醒一次。
还有wkup引脚的唤醒功能:wkup引脚默认下拉,引脚悬空,就是低电平,把线插到高电平,待机模式唤醒。
在这里插入图片描述
在这里插入图片描述

小实验:验证待机模式省电

手册说待机模式的电流只有3微安左右,为此进行了测试,

  • 这里我单独找了个stm32板子,把这个电源供电线正极给剪断,串联一个万用表测电流。
    当然最开始我直接测试哈,待机模式的电流高达一点多毫安,远超手册里说的3微安,但首先很明显这个电源指示灯肯定是耗电的,所以我先把这个电源指示灯去掉了,再测试电流仍然有几百微安。

    那说明还有别的东西耗电,之后我就把板子背面的这个LDO稳压器去掉了,这个LDO虽然我们并没有用到哈,但接上它就会有电流损耗,最后去掉电源指示灯和LDO之后,待机模式的电流就下降到3微安了。

首先,万用表接到200mA电流档,最开始看到正常工作的电流
在这里插入图片描述
之后等一会,进入待机模式,这个供电电流瞬间变为0,万用表换到200微安档,可以看到,目前待机的供电电流是3.3微安。
在这里插入图片描述

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

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

相关文章

张大哥笔记:5种信息差赚钱模式

从古至今,赚钱最快的路子就一个,而且从未改变,那就是信息差!在商业活动中,信息不对称现象普遍存在,如果你善于利用这些信息差的话,就可以赚到钱! 1、价格的信息差 商品价格在不同地…

python pyautogui实现图片识别点击失败后重试

安装库 pip install Pillow pip install opencv-python confidence作用 confidence 参数是用于指定图像匹配的信度(或置信度)的,它表示图像匹配的准确程度。这个参数的值在 0 到 1 之间,数值越高表示匹配的要求越严格。 具体来…

ConcurrentHashMap(应对并发问题的工具类)

并发工具类 在JDK的并发包里提供了几个非常有用的并发容器和并发工具类。供我们在多线程开发中进行使用。 5.1 ConcurrentHashMap 5.1.1 概述以及基本使用 在集合类中HashMap是比较常用的集合对象,但是HashMap是线程不安全的(多线程环境下可能会存在问题)。为了…

可一件转化的视频生成模型:快手官方大模型“可灵”重磅来袭!

可一件转化的视频生成模型“可灵”重磅来袭! 前言 戴墨镜的蒙娜丽莎 达芬奇的画作《蒙娜丽莎的微笑》相信大家是在熟悉不过了,可《戴墨镜的蒙娜丽莎》大家是不是第一次见?而且这还不是以照片的形式,而是以视频的形式展示给大家。 …

Spring AOP实战--之优雅的统一打印web请求的出参和入参

背景介绍 由于实际项目内网开发,项目保密,因此本文以笔者自己搭建的demo做演示,方便大家理解。 在项目开发过程中,团队成员为了方便调试,经常会在方法的出口和入口处加上log输出,由于每个人的log需求和输…

奔驰EQS SUV升级原厂主动式氛围灯效果展示

以下是一篇关于奔驰 EQs 升级原厂主动氛围灯案例的宣传文案: 在汽车科技不断演进的今天,我们自豪地为您呈现奔驰 EQs 升级原厂主动氛围灯的精彩案例。 奔驰 EQs,作为豪华电动汽车的典范,其卓越品质与高端性能有目共睹。而此次升…

CVPR 2024盛况空前,上海科技大学夺得最佳学生论文奖,惊艳全场

CVPR 2024盛况空前!上海科技大学夺得最佳学生论文奖,惊艳全场! 会议之眼 快讯 2024 年 CVPR (Computer Vision and Pattern Recogntion Conference) 即国际计算机视觉与模式识别会议,于6月17日至21日正在美国西雅图召…

手把手教你java CPU飙升300%如何优化

背景 今天有个项目运行一段时间后,cpu老是不堪负载。 排查 top 命令 TOP 命令 top t 按cpu 排序 top m 按内存使用率排序 从上面看很快看出是 pid 4338 这个进程资源消耗很高。 top -Hp pid top -Hp 4338 找到对应线程消耗的资源shftp cpu占用进行排序&#xf…

【Java】已解决java.net.ProtocolException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.net.ProtocolException异常 在Java的网络编程中,java.net.ProtocolException异常通常表示在网络通信过程中,客户端或服务器违反了某种协议规则。…

计算机组成原理 | 计算机系统概述

CPI:(Clockcycle Per Instruction),指每条指令的时钟周期数。 时钟周期:对CPU来说,在一个时钟周期内,CPU仅完成一个最基本的动作。时钟脉冲是计算机的基本工作脉冲,控制着计算机的工作节奏。时钟周期 是一个时钟脉冲所…

除了百度,还有哪些搜索引擎工具可以使用

搜索引擎成是我们获取知识和信息不可或缺的工具。百度作为国内最大的搜索引擎,全球最大的中文搜索引擎,是许多人的首选。那么除了百度,还有哪些搜索引擎可以使用呢?小编就来和大家分享国内可以使用的其他搜索工具。 1. AI搜索 AI…

梯度提升决策树(GBDT)的训练过程

以下通过案例(根据行为习惯预测年龄)帮助我们深入理解梯度提升决策树(GBDT)的训练过程 假设训练集有4个人(A、B、C、D),他们的年龄分别是14、16、24、26。其中A、B分别是高一和高三学生&#x…

大模型时代,新手和程序员如何转型入局AI行业?

在近期的全国两会上,“人工智能”再次被提及,并成为国家战略的焦点。这一举措预示着在接下来的十年到十五年里,人工智能将获得巨大的发展红利。技术革命正在从“互联网”向“人工智能”逐步迈进,我将迎来新一轮技术革新和人才需求…

ASP.NET Core 6.0 启动方式

启动方式 Visualstudio 2022启动 IIS Express IIS Express 是一个专为开发人员优化的轻型独立版本的 IIS。 借助 IIS Express,可以轻松地使用最新版本的 IIS 开发和测试网站。 控制台版面 直接在浏览器输入监听的地址,监听的是 http://localhost:5137 脚本启动 dotnet run…

C++11 右值引用和移动语义

目录 1.左值引用和右值引用 2.右值引用使用场景(移动语义)和意义 3.右值引用引用左值及其一些更深入的使用场景分析 4.完美转发 1.左值引用和右值引用 传统的C语法中就有引用的语法,而C11中新增了的右值引用语法特性,所以从现…

Verilog:【8】基于FPGA实现SD NAND FLASH的SPI协议读写

在此介绍的是使用FPGA实现SD NAND FLASH的读写操作,以雷龙发展提供的CS创世SD NAND FLASH样品为例,分别讲解电路连接、读写时序与仿真和实验结果。 目录 1 视频讲解 2 SD NAND FLASH背景介绍 3 样品申请 4 电路结构与接口协议 4.1 SD NAND 4.2 SD NAND测…

机器学习算法的电影推荐系统以及票房预测系统

一、实验概述 1. 实验目标 本项目希望基于电影数据集,依据电影的简介、关键词、预算、票房、用户评分等特征来对电影进行分析,并完成以下任务: 对电影特征的可视化分析对电影票房的预测多功能个性化的电影推荐算法 2. 数据集 针对票房预…

AIGC-CVPR2024best paper-Rich Human Feedback for Text-to-Image Generation-论文精读

Rich Human Feedback for Text-to-Image Generation斩获CVPR2024最佳论文!受大模型中的RLHF技术启发,团队用人类反馈来改进Stable Diffusion等文生图模型。这项研究来自UCSD、谷歌等。 在本文中,作者通过标记不可信或与文本不对齐的图像区域&…

vulnhub靶场之FunBox-11

一.环境搭建 1.靶场描述 As always, its a very easy box for beginners. Add to your /etc/hosts: funbox11 This works better with VirtualBox rather than VMware. 2.靶场下载 https://www.vulnhub.com/entry/funbox-scriptkiddie,725/ 3.靶场启动 二.信息收集 1.寻找靶…

通过腾讯云TDSQL TCPTCE(MySQL版)认证考试秘籍宝典

腾讯云TDSQL(MySQL版)交付运维高级工程师TCCP证书展示 腾讯云TDSQL(MySQL版)交付运维专家TCCE考试成绩、证书展示 认证类型与级别 TCCA:入门级(初级) TCCP:高级(中级) TCCE:专家级(高级) 考试形式 考试是在线考试,考生需要在腾讯云大学官网上完成。 腾讯云TDSQ…