STM32待机唤醒

STM32有3中低功耗模式:
1)睡眠模式(CM3 内核停止,外设仍然运行)
2)停止模式(所有时钟都停止)
3)待机模式(1.8V 内核电源关闭)
在运行模式下,我们也可以通过降低系统时钟关闭 APB 和 AHB 总线上未被使用的外设的时钟来降低功耗。三种低功耗模式一览表见表 21.1.1 所示
表21.1。1
在这三种模式中,最低功耗的属于第三种模式,即待机模式,最低只需要2uA的电流。停机模式是次低功耗的,其典型的电流消耗在 20uA 左右。最后就是睡眠模式了。
下边就讲一下待机模式如何进入以及如何运行。该模式是在 CM3 深睡眠模式时关闭电压调节器。整个 1.8V 供电区域被断电。PLL、HSI 和 HSE 振荡器也被断电。SRAM 和寄存器内容丢失。仅备份的寄存器和待机电路维持供电。
在这里插入图片描述
void Sys_Standby(void)
{
RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外设时钟。因为低功耗模式属于电源管理的一部分,要进入低功耗模 式就需要对PWR相关的寄存器进行相关的设置。要操作寄存器首先就要打开时钟。 PWR是挂载在APB1总线下的。
PWR_WakeUpPinCmd(ENABLE);//使能唤醒引脚功能----->打开开关。 //Enables or disables the WakeUp Pin functionality.
PWR_EnterSTANDBYMode(); //调用库函数,进入待机模式【】。此函数在stm32f10x_pwr.c中。

/******************************************************************************
这是库中的原型。进入的那几个步骤。
	void PWR_EnterSTANDBYMode(void)
	{
	 // Clear Wake-up flag 
	 PWR->CR |= PWR_CR_CWUF;
	 /* Select STANDBY mode,掉电深睡眠模式-----PDDS位置1  */
	 PWR->CR |= PWR_CR_PDDS;
	 /* Set SLEEPDEEP bit of Cortex System Control Register */
	 //进入待机模式, 首先要设置 SLEEPDEEP 位(该位在系统控制寄存器(SCB_SCR)的第二位,最后执行 WFI 指令开始进入待机模式,并等待 WK_UP中断的到来。
	 SCB->SCR |= SCB_SCR_SLEEPDEEP;
	/* This option is used to ensure that store operations are completed */
	#if defined ( __CC_ARM   )
	 __force_stores();
	#endif
	 /* Request Wait For Interrupt */
	__WFI();
	}
******************************************************************************/

}

//进入待机模式
void Sys_Enter_Standby(void)
{			 
	RCC_APB2PeriphResetCmd(0X01FC,DISABLE);	//¸复位福所有的IO
	Sys_Standby();
}

//检测WKUP引脚的信号
//返回1:连续按下3S钟以上
//  返回0:错误的触发
unsigned char check(void)
{
	unsigned char t = 0;//记录按下的时间
	//LED0 --->PB0
	GPIO_ResetBits(GPIOB,GPIO_Pin_5);//打开LED0
	while(1)
	{
		if(1 == GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) )//WKUP按下---WKUP ---PA0
		{
			t++;
			delay_ms(30);
			if(t>=100)//3s钟到了
			{
				GPIO_ResetBits(GPIOB,GPIO_Pin_5);//LED0亮,返回1
				return 1;
			}		
		}else
		{
			GPIO_SetBits(GPIOB,GPIO_Pin_5);	//LED0灭,返回0
			return 0;//
		}
	}
}


//中断服务函数 使用中断线0
	void EXTI0_IRQHandler(void)
	{ 		    		    				     		    
		EXTI_ClearITPendingBit(EXTI_Line0); //清除中断线0上的标志位	  
		if(check())//检测是否关机?
		{		  
			Sys_Enter_Standby();  
		}
	}


void WKUP_Init(void)
{
	GPIO_InitTypeDef GPIO_Instructure1;
	NVIC_InitTypeDef NVIC_Instructure;
	EXTI_InitTypeDef EXIT_Instructure;
	
	
	//时钟使能 GPIOA挂载在APB2的总线下。要设置那个GPIO pin被用于中断线就要打开AFIO时钟。 这里一同打开。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
	GPIO_Instructure1.GPIO_Pin = GPIO_Pin_0;//PA.0
	GPIO_Instructure1.GPIO_Mode = GPIO_Mode_IPD;//上拉输入
	GPIO_Init(GPIOA,&GPIO_Instructure1);//初始化IO
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
	//设置GPIOA0作为中断线
	
	EXIT_Instructure.EXTI_Line = EXTI_Line0;//中断线0
	EXIT_Instructure.EXTI_Mode = EXTI_Mode_Interrupt;//使用中断模式而不是事件模式
	EXIT_Instructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发
	EXIT_Instructure.EXTI_LineCmd =ENABLE;//使能中断命令
	EXTI_Init(&EXIT_Instructure);//初始化外部中断
	
	//
	NVIC_Instructure.NVIC_IRQChannel = EXTI0_IRQn;		//使能按键所在的外部中断通道
	NVIC_Instructure.NVIC_IRQChannelSubPriority = 2;	//先优先级2级
	NVIC_Instructure.NVIC_IRQChannelPreemptionPriority = 2;//´子优先级2级
	NVIC_Instructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
	NVIC_Init(&NVIC_Instructure);//根据NVIC_Instructure所设置的参数初始化NVIC寄存器

	if(check()==0) 
		Sys_Standby();    //不是开机,是进入待机模式

}
	
	int main(void)
	{
	SystemInit();  //我配置的时钟有点问题,在这里调用系统时钟使之到72M。
	delay_init();
	LED_Init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2,2位抢占优先级,2位响应优先级。
	WKUP_Init();
	while (1)
	{
	GPIO_WriteBit(GPIOB, GPIO_Pin_5, (BitAction)((1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5))));
	delay_ms(1000);
	}
	return 0;	
	}

刚开始学习,个人的一点总结。有不对的地方欢迎大家指针批评。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值