30_待机唤醒实验
创始人
2024-03-21 03:15:40
0

目录

待机唤醒

STM32的3种低功耗模式:

相关寄存器讲解

相关库函数介绍

待机唤醒配置步骤:

实验源码:


待机唤醒

很多单片机有低功耗模式,STM32也不例外。在系统或者电源复位后,微控制器出于运行状态之下, HCLK为CPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。

STM32的3种低功耗模式:

1.睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行。

2.停止模式:所有时钟都已停止。1.8V内核电源工作。PLL,HIS和HSE RC振荡器功能禁止。寄存器和SRAM内容保留。

3.待机模式: 1.8V内核电源关闭。只有备份寄存器和待机电路维持供电。寄存器和SRAM内容全部丢失。实现最低功耗。

在运行模式下,可以通过下面方式降低功耗:

1.降低系统时钟。2.关闭APB和AHB总线上未被使用的外设时钟、

 

 

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

在待机模式下,所有的I/O引脚处于高阻态,除了以下引脚:

1.复位引脚(始终有效)

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

3.被使能的唤醒引脚

待机模式理想状态下,只需要2uA电流。停机模式下典型电流为20uA。

相关寄存器讲解

PWR_CR电源控制寄存器

1.设置PDDS位进入深度睡眠时进入待机模式。

2.设置CWUF位,清除之前的WUF唤醒位。

PWR_CSR电源控制/状态寄存器

1.设置EWUP,使能WKUP引脚用于待机模式唤醒。

 2.WUF唤醒标志,用来判断是否发生唤醒事件。

相关库函数介绍

void PWR_EnterSTOPMode();//进入停机模式
void PWR_EnterSTANDBYMode(void);//进入待机模式
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);

待机唤醒配置步骤:

1.使能电源时钟。

因为要配置电源控制寄存器,所以必须先使能电源时钟。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

2.设置WK_UP引脚作为唤醒源。

设置PWR_CSR的EWUP位,使能WK_UP用于将CPU从待机模式唤醒。

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

3.设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。

void PWR_EnterSTANDBYMode(void);

实验源码:

1.首次下载程序进去会执行Gpio,Rcc初始化程序,当进入Wkup_Init初始化时配置了外部中断最后判断如果按键没有按下3秒执行待机模式。(注意待机模式中断不会关)

2.此时在按下唤醒按键CPU是马上重新从main函数开始跑的,初始化到Wkup_Init按下3s就不会进入待机状态,程序正常跑,否则继续待机。

3.正常模式下,按下按键会进入中断里面按下3s会执行待机(注意正常跑的时候是配好了外部中断的所以进入待机的时候按下CUP又会执行2步骤)

/********************************************************************************* @file           : user_rcc_config.c* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "user_rcc_config.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*//*!\brief		RCC配置\param[in]	none\param[out]	none\retval 	none
*/
void Rcc_config(void)
{	/*使能UART1时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);/*使能GPIOA*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);/*复用功能时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);}/************************************************************** END OF FILE ****/
/********************************************************************************* @file           : user_gpio.c* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "user_gpio.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*//*!\brief		GPIO初始化函数\param[in]	none\param[out]	none\retval 	none
*/
void Gpio_Init(void)
{	/*GPIO结构体*/GPIO_InitTypeDef GPIO_InitTypeDefstruct;/*UART1发送引脚配置*/GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_AF_PP;//推挽复用输出GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_9;GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;/*写入结构体到GPIOA*/GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);/*UART1接收引脚配置*/GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_10;GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;/*写入结构体到GPIOA*/	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);/*唤醒引脚初始化*/GPIO_InitTypeDefstruct.GPIO_Pin =GPIO_Pin_0;	 //PA.0GPIO_InitTypeDefstruct.GPIO_Mode =GPIO_Mode_IPD;//上拉输入GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;/*写入结构体到GPIOA*/	GPIO_Init(GPIOA, &GPIO_InitTypeDefstruct);	}/************************************************************** END OF FILE ****/
/********************************************************************************* @file           : user_pwr.c* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "user_pwr.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*//*!
\brief		    待机函数\param[in]	none\param[out]	none\retval 	none
*/
void Sys_Standby(void)
{  /*使能PWR外设时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	/*使能唤醒管脚功能*/PWR_WakeUpPinCmd(ENABLE); /*进入待机(STANDBY)模式*/PWR_EnterSTANDBYMode();	 
}/*!
\brief		    进入待机函数\param[in]	none\param[out]	none\retval 	none
*/
void Sys_Enter_Standby(void)
{			/*复位所有IO*/RCC_APB2PeriphResetCmd(0X01FC,DISABLE);	/*正式进入待机模式*/Sys_Standby();
}/*!\brief		判断是否是3秒\param[in]	none\param[out]	none\retval 	1表示按下3秒,0表示不足3秒
*/
uint8_t Check_Wkup(void) 
{/*记录时间*/u8 t=0;		while(1){if(PAin(0)) //按键检测{t++;			//已经按下了 delay_ms(30);if(t>=100)		//按下超过3秒钟{return 1; 	//按下3s以上了}}else { return 0; 		//按下不足3秒}}
}/*!\brief		唤醒初始化\param[in]	none\param[out]	none\retval 	none
*/
void Wkup_Init(void)
{	/*中断控制器结构体*/NVIC_InitTypeDef NVIC_InitStructure;/*外部中断线结构体*/EXTI_InitTypeDef EXTI_InitStructure;/*选择GPIOA.0为外部中断源*/GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);	/*外部中断配置*/EXTI_InitStructure.EXTI_Line = EXTI_Line0;	//设置按键所有的外部线路EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//设外外部中断模式:EXTI线路为中断请求EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //上升沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;/*写入外部中断线*/EXTI_Init(&EXTI_InitStructure);	/*配置中断控制器*/NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道/*写入中断控制器*/NVIC_Init(&NVIC_InitStructure); if(Check_Wkup() == 0){	/*待机模式*/Sys_Standby();}}/*!\brief		EXTI0_IRQHandler\param[in]	none\param[out]	none\retval 	none
*/
void EXTI0_IRQHandler(void)
{ 		    		    				     		    EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位		  if(Check_Wkup()){		  Sys_Enter_Standby();  }
}/************************************************************** END OF FILE ****/
/********************************************************************************* @file           : user_uart.c* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "user_uart.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/extern uint16_t USART_RX_STA;
extern uint8_t USART_RX_BUF[200];/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/
#if 1
#pragma import(__use_no_semihosting)  
/*实现Printf代码*/
struct __FILE 
{ int handle; }; 
FILE __stdout;       void _sys_exit(int x) 
{ x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   USART1->DR = (u8) ch;      return ch;
}
#endif /*!\brief		UART1初始化\param[in]	none\param[out]	none\retval 	none
*/void Uart1_Init(u32 bound)
{/*UART结构体*/USART_InitTypeDef USART_InitTypeDefstruct;/*UART结构体配置*/USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位/*写入USART1*/USART_Init(USART1,&USART_InitTypeDefstruct);/*使能串口1*/USART_Cmd(USART1,ENABLE);}/*!\brief		UART1中断服务函数\param[in]	none\param[out]	none\retval 	none
*/void USART1_IRQHandler(void)
{}/************************************************************** END OF FILE ****/
/********************************************************************************* @file           : user_mian.h* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include 
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "user_pwr.h"/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
//最多一次接收200个字节
uint8_t USART_RX_BUF[200];
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
uint16_t USART_RX_STA=0;       //接收状态标记	 
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/int main(void){	/*配置系统中断分组为2位抢占2位响应*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/*延时函数初始化*/delay_init();/*RCC配置*/Rcc_config();/*GPIO初始化*/ Gpio_Init();/*初始化Wkup*/Wkup_Init();/*USART1初始化*/Uart1_Init(9600);/*死循环*/ while(1){printf("正常运行\r\n");}}/************************************************************** END OF FILE ****/

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...