待机模式中WKUP上升沿模拟开机与关机

news2024/9/27 18:43:00

本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发

目录

前言

待机模式

代码 

wkup.h

wkup.c 

main.c 

使用注意


前言

建议先阅读下面的博客中待机模式部分。本博客主要分享代码-基于待机模式WKUP引脚的上升沿实现类似长按开机与关机的功能

【STM32】PWR电源控制(低功耗模式)_stm32进入待机模式-CSDN博客

待机模式

待机模式时可选择功能

待机模式下的输入/输出端口状态

在待机模式下,所有的I/O引脚处于高阻态(浮空输入),除了以下的引脚(微控制器从待机模式退出):

● 复位引脚(始终有效)

● 当被设置为防侵入或校准输出时的TAMPER引脚

● WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位

从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。 从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出 

代码 

PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能

EWUP:使能WKUP引脚

0:WKUP引脚为通用I/O。WKUP引脚上的事件不能将CPU从待机模式唤醒

1:WKUP引脚用于将CPU从待机模式唤醒,WKUP引脚被强置为输入下拉的配置(WKUP引脚上的上升沿将系统从待机模式唤醒)

注:在系统复位时清除这一位。

代码思路 

不按按键PA0,下载程序后,在WKUP初始化函数中默认进入待机模式,执行不到while内,长按PA0,系统复位,程序从头执行。执行到WKUP初始化函数时,不进入待机模式,可以执行到while内,长按按键PA0,在中断函数里进入待机模式,如此重复下去,便可实现WKUP上升沿模拟开机与关机

wkup.h

#ifndef __WKUP_H
#define __WKUP_H	 

					    
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)			//检测外部WK_UP按键是否按下
	 
void WKUP_Init(void); 			//PA0 WKUP唤醒初始化
uint8_t Check_WKUP(void);  			//检测WKUP脚的信号
void Sys_EnterStandby(void);	//系统进入待机模式

#endif


wkup.c 

#include "stm32f10x.h"                  // Device header
#include "wkup.h"
#include "LED.h"
#include "Delay.h"


void Sys_Standby(void);//系统进入待机模式  

//PA0初始化作为普通IO口并开启外部中断,中断服务函数内检测到边沿进入待机模式
void WKUP_Init(void)
{		  		  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟

	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;	 //PA.0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

    //使用外部中断方式
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);	//中断线0连接GPIOA.0

	EXTI_InitTypeDef EXTI_InitStructure;
  	EXTI_InitStructure.EXTI_Line = EXTI_Line0;	
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//EXTI0线路为中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  	//上升沿触发
 	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	

	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
	NVIC_Init(&NVIC_InitStructure); 

	if(Check_WKUP() == 0) Sys_Standby();    //默认进入待机模式 ,除非该语句执行前长按WKUP 
	
}
//PA0设置作为WKUP引脚,且系统进入待机模式
void Sys_Standby(void)
{  
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	//使能PWR外设时钟
	PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
	PWR_EnterSTANDBYMode();	  //进入STANDBY模式 		 
}

//关闭外设后系统进入待机模式
void Sys_EnterStandby(void)
{			 
	RCC_APB2PeriphResetCmd(0X01FC, DISABLE);	//复位所有GPIO口
	/*
		此处关闭其他外设
	*/
	Sys_Standby();
}

//检测WKUP脚的信号
//返回值 1:连续按下3s以上;0:错误的触发	
uint8_t Check_WKUP(void) 
{
	uint8_t t = 0;	//记录按下的时间
	LED1_ON(); //亮灯 
	while(1)
	{
		if(WK_UP)
		{
			t++;			//已经按下了 
			Delay_ms(30);
			if(t >= 100)		//按下超过3秒钟
			{
				LED1_ON();	 	//点亮 
				return 1; 	//按下3s以上了
			}
		}else 
		{ 
			LED1_OFF();
			return 0; //按下不足3秒
		}
	}
}

//检测到PA0脚的一个上升沿进入中断 
void EXTI0_IRQHandler(void)
{ 		    		    				     		    
	EXTI_ClearITPendingBit(EXTI_Line0); // 清除EXTI0的标志位		  
	if(Check_WKUP())//连续按下3s以上
	{		  
		Sys_EnterStandby(); //关机
	}
} 

main.c 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "wkup.h"
#include "LED.h"

int main(void)
{
	OLED_Init();
	LED_Init();
	WKUP_Init();//默认进入待机模式;WK_UP上升沿唤醒待机模式,程序从头执行,必须长按WK_UP才不进入待机模式,相当于开机
	while (1)
	{
		//while循环内,通过外部中断检测WK_UP高电平时间进入待机模式
		LED2_Turn();
		Delay_ms(300);
		LED2_Turn();
		Delay_ms(300);
	}
}

使用注意

中断函数中Check_WKUP( )函数延时过多,建议用定时器中断检测按键时间,不阻塞其他程序的执行。

//检测到PA0脚的一个上升沿进入中断 
void EXTI0_IRQHandler(void)
{ 		    		    				     		    
	EXTI_ClearITPendingBit(EXTI_Line0); // 清除EXTI0的标志位		  
	if(Check_WKUP())//连续按下3s以上
	{		  
		Sys_EnterStandby(); //关机
	}
} 

void Sys_EnterStandby(void)函数里面,我们要在进入待机模式前把所有开启的外设全部关闭,我们这里仅仅复位了所有的 IO 口,使得 IO 口全部为浮空输入。其他外设(比如 ADC 等),大家根据自己所开启的情况进行一一关闭就可,这样才能达到最低功耗! 

void Sys_EnterStandby(void)
{			 
	RCC_APB2PeriphResetCmd(0X01FC, DISABLE);	//复位所有GPIO口
	/*
		此处关闭其他外设
	*/
	Sys_Standby();
}

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

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

相关文章

TikTok云手机解决运营效率低、封号问题

TikTok,一个拥有30亿下载量、10亿活跃用户的全球热门平台,已成为众多出海商家的首选运营阵地。其玩法与国内抖音相似,为运营者提供了熟悉的操作环境,降低了上手难度。然而,随着TikTok的快速发展,运营者们也…

德之匠信息化阶段模型

今天适逢仲秋佳节,祝大家幸福安康! 春生、夏长、秋天也是我们作为知识工作者最开心的季节。经历了项目实践、课题研究,终于能思有一得,是世上第一等的好事。 这个题目的背景是这样。近期我们在做一批中长期信息化项目的分析和总…

深度学习基础案例5--运用动态学习率构建CNN卷积神经网络实现的运动鞋识别(测试集的准确率84%)

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 前几天一直很忙,一直在数学建模中,没有来得及更新,接下来将恢复正常这一次的案例很有意思:在学习动态调整…

【IP协议】解决 IP 地址不够用的问题(IP地址管理:动态分配、NAT、Ipv6)

文章目录 方案一、动态分配 IP 地址方案二、NATNAT 机制的缺点 方案三、IPv6 方案一、动态分配 IP 地址 一个设备上网就分配 IP,不上网就先不分配(权宜之计) 方案二、NAT 网络地址转换 以一当千,使用一个 IP,代表一大…

Golang | Leetcode Golang题解之第404题左叶子之和

题目: 题解: func isLeafNode(node *TreeNode) bool {return node.Left nil && node.Right nil }func sumOfLeftLeaves(root *TreeNode) (ans int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {node : q[0]q q[1:]if no…

anaconda 离线安装PySimpleGUI

下载离线py包 PySimpleGUI-5.0.6-py3-none-any.whl(官网)pyasn1-0.6.1-py3-none-any.whl(清华镜像)rsa-4.9-py3-none-any.whl(清华镜像) 打开Anaconda Prompt 测试 # -*- utf-8 -*- import PySimpleGUI …

同城找搭子小程序有哪些?找搭子社交软件测评笔记分享

寻找搭子不再迷茫!今日测评几款热门找搭子小程序,为你开启全新社交体验。真实体验,深度剖析,帮你找到最适合的搭子平台,快来一探究竟。 1. 咕哇找搭子小程序:这是一个实名制的找搭子交友平台。正是由于实名…

任务通知(Task Notifications)

任务通知简介 相对于以前使用 FreeRTOS 内核通信的资源, 必须创建队列、 二进制信号量、计数信号量或事件组的情况, 使用任务通知显然更灵活。 按照 FreeRTOS 官方的说法, 使用任务通知比通过信号量等 IPC 通信方式解除阻塞的任务要快 45%&a…

基于RFID的门禁系统的设计(论文+源码)

1系统方案设计 通过需求分析,基于RFID的门禁系统总体设计框图。系统采用STM32单片机作为系统主控核心,利用独立按键与RFID识别模块能够实现门禁系统密码与IC卡开门功能。WiFi模块实现系统与手机APP的通信,用户可以通过手机APP进行门禁开关操…

怀孕之天赋共享:提高智商

想办法怀个哪吒享受三年,哈哈哈哈哈 话说我们有个同事,是属于憨得有点愣那种,情商也低。怀孕以后突然有一天我觉得她聪明了好几个数量级!反应也快了说话也会说了,我说是不是她的宝宝给她提高了智商?后来生…

Redis学习——数据不一致怎么办?更新缓存失败了又怎么办?

文章目录 引言正文读写缓存的数据一致性只读缓存的数据一致性删除和修改数据不一致问题操作执行失败导致数据不一致解决办法 多线程访问导致数据不一致问题总结 总结参考信息 引言 最近面试快手的时候被问到了缓存不一致怎么解决?一开始还是很懵的,因为…

Git 的使用以及vscode 下git 的使用(一)

1、git 和svn Git 和 SVN 都是版本控制系统,它们都用于管理代码的版本,但它们之间有一些显著的区别: 分布式 vs 集中式:Git 是一个分布式版本控制系统,这意味着每个开发者都拥有整个代码库的完整副本,并且…

3DTiles —— 三维瓦片

文章目录 一、glTF二、3DTiles1.3dTiles的特点2.一个简单的3dTiles数据示例3.Tileset——(三维)瓦片数据集——.json顶级属性概览(必需):asset、root、geometricError其他属性root、children、refine、content、boundingVolumechildrenrefine 细化bounding volumes …

大棚分割数据集,40765对影像,16.9g数据量,0.8米高分二,纯手工标注(arcgis标注)的大规模农业大棚分割数据集。

数据集名称: )“Greenhouse Segmentation Dataset (GSD)” 数据集规模: 包含40,765对用于大棚分割的影像数据,每对影像包括一张原始图像和相应的分割标签图。 数据量: 总数据量约为16.9GB,适合存储在现…

推荐这款神器:Perplexity

今天推荐是一款AI搜索引擎,还支持gpt-4模型的使用,虽然4小时只能使用5次,但是相比于常规的搜索引擎,在某些方面还是很强的,个人感觉优于newbing。 页面简洁,没有广告,内容丰富,功能…

JVM面试真题总结(十)

文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 是否所有对象都分配在堆内存上? 在Java中,对象主要是…

SVM——支持向量机的学习入门

1、推荐文章 1、一文看懂SVM算法 2、图解机器学习|支持向量机模型详解 3、支持向量机的直观理解 2、分类问题 假设你的大学开设了一门机器学习(ML)课程。课程导师发现数学或统计学好的学生表现最佳。随着时间的推移,积累了一些数据&…

Mysql的高级查询:SQL关联查询(内连接/外连接/自连接)/子查询

一.关联查询: 定义:关联查询又叫连接查询 常见:内连接/外连接/自连接 1.内连接(无存在主从表) 语法:inner join ...on 定义:组合两个表的记录,返回关联字段相符的记录,也就是返…

【LeetCode】每日一题 2024_9_15 与车相交的点(差分)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动! 今天的题目曾经的我做过了 . . . 又是复习的一天 题目:与车相交的点 代码与解题思路 func numberOfPoints(nums [][]int) (ans int) { diff : [102]int{}for _, p : range nums {diff[p[0]]d…

Orchestrator 与 Mysql 8.0 的兼容性

一、看图识别问题 二、Mysql 8.0 从 MySQL 8.0.22 开始,使用SHOW REPLICA STATUS代替SHOW SLAVE STATUS,该语句从该版本开始已弃用。 所以:Mysql 8.0.22前可以用Orchestartor