STM32 low power standby mode + rising edge of WKUP pin to wake up

Today I’m going to talk about STM32 energy-saving modules, yes, this title already tells you, right? Oh, yes, the title is written, so let's get back to business. As for how STM32 can achieve energy saving, the Chinese teacher said to leave suspense and follow the author, that is, follow me.

Everyone open the Chinese reference manual of STM32 (you can read it, I read it, and then take a screenshot), there are detailed annotations about the low power consumption mode of STM32, and suddenly I don’t want to take a screenshot.

1. Sleep mode (Cortex™-M3 core stops, all peripherals including Cortex-M3 core peripherals, such as NVIC, system clock (SysTick), etc. are still running)

2. Stop mode (all clocks have been stopped)

3. Standby mode (1.8V power off) (a mode specifically introduced in our blog, which is also the mode with the lowest power consumption)

The three photos are now attached, I hope the audience will appreciate them, and please pay attention to my graffiti. The little brother is grateful:

Aha, is this photo amazing? I took the three old guys' family status more seriously. Comparison, and from the photos, we can also see how to enter, how to wake them up, and what influences have been revealed to us, it can be said to be terrifying, so I ask everyone to pay attention to my beautiful graffiti is reasonable, ha.

In this blog, we will use the rising edge of the WKUP pin to wake up the MCU. I'm sorry, we always mark the rising edge as a small Shenyang, so we will specifically introduce the implementation method of standby wake-up.

So how do we enter the standby mode? How to wake up again?

See the red number in "Enter", right? That's right, we just need to follow this step to set the corresponding register, then, I call? ? ? What is it? ? Okay, please allow me to introduce:

1. Where is the SLEEPDEEP bit in the Cotex_M3 system control register? ? Everyone, please turn to page 182 of the "Authoritative Guide" to see the table. Of course, you don't need to open it here., because I have taken a screenshot:

2. The PDDS bit in the power control register (PWR_CR): Please see the register bit:

3. So
 far, the EWUP bit in the power control/status register (PWR_CSR) has completed the task of entering the standby mode through these three steps. How do we achieve it through the program? Aha! Kushen appears. The system is crashing, please wait, please contact 10086 for details.

Uh, there was an accident, no hurry, then let’s take a look at how to exit the standby mode: reproduce a picture:
 see it,, here we use one of the ways to wake up: WKUP pin rise There are three words: edge, attention, attention to this rising edge. As for why you should pay attention to the rising edge, I have a purpose when I put it here. Remember, the reason why you want to pay attention at this time must be with me. It’s not the same when it’s mentioned, let’s smirk here first,

How do we wake up? ?

Dear, we wake up by an external interrupt trigger, so please look at the code:

void Wkup_Init(void)
{
    
       
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;	
	KEY_Init();//我的IO初始化在按键里已经初始化了	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); 
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line0; //PA0        
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
	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 = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
	NVIC_Init(&NVIC_InitStructure);   
	
	if(Check_up() == 0)   //系统初始化后由于没有按下按键,所以系统直接进入了待机模式了,所以下载了程序没有任何反应。需要人为的唤醒:死猪,就知道睡,快醒、、
	{
    
    
	Sys_Standby();         //进入待机模式
	}      
}
//正常模式下会运行中断服务函数,而待机模式下则不会运行中断服务函数,因为待机模式下MCU不工作,所以上升沿的作用也仅仅是唤醒。
//在这里提醒:唤醒只需要上升沿,所以从待机模式切换到正常模式下从始至终都不会执行中断服务函数
//在这里,知道我为什么要在上面提醒大家要注意上升沿了吧、(下面还有)、
//至于为什么不会执行,待会我还会给出解释。

void EXTI0_IRQHandler(void)
{
    
                                                              
	EXTI_ClearITPendingBit(EXTI_Line0); 
	if(Check_up())
	{
    
              
		Sys_Enter_Standby();  
	}
}

Will you be familiar with the above code? ? I won’t explain it here, so let’s focus on the steps

1. Enable PWR clock: RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

2. The function of enabling wakeup: PWR_WakeUpPinCmd(ENABLE);

3. Enter standby mode: PWR_EnterSTANDBYMode();

Please see the code:

void Sys_Standby(void) //在唤醒初始化中调用
{
    
       
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
   PWR_WakeUpPinCmd(ENABLE);
   PWR_EnterSTANDBYMode();        
}
void Sys_Enter_Standby(void)//在中断函数里调用,用来复位,然后进入待机模式
{
    
                 
    RCC_APB2PeriphResetCmd(0X01FC,DISABLE);    //在这里只是复位了IO口、、至于0x01fc是怎么来的、、大家请看RCC_APB2RSTR(下图)
    Sys_Standby();
}

Finally, we give a processing program for key detection. Here, 3S is just an effect, you can use it, or it can be longer, it’s up to you (atomic program, don’t tell me about pirating)

u8 Check_up(void)
{
    
    
      u8 t = 0;
      u8 tx = 0;
      LED0 = 0;
      while(1)
        {
    
    
       if(KEY3 == 1) //检测到按键按下
             {
    
    
          t++;
                  tx = 0;
       }
             else
             {
    
    
                 tx++;
                  if(tx > 3)
                    {
    
    
                        LED0 = 1;
                        return 0;      //错误按键或者按键时间不够
                    }                        
             }
             delay_ms(30);
             if(t > 100)       //100*30ms = 3s
             {
    
    
                   LED0 = 0;
                   return 1;// 3s
        }
    }
}

Seeing this, some people may not understand the logic in the interrupt service function. Here I will give an explanation:

/*从正常运行模式切换到待机模式 按住wkup键 外部中断0中断被触发 
执行中断服务函数 Check_up()函数开始检测 如果时间没超过3s 返回零 
这时工作在正常运行模式 如果按住时间超过了3s 返回值为1 进入待机模式
我们的程序在刚开始运行时就是没有按键按下,所以没有上升沿,初始化函
数里条件成立,从而进入了待机模式:请看初始化的代码:*/
if (Check_up() == 0)
{
    
    
	Sys_Standby();         //进入待机模式
}  
/*从待机模式切换到正常运行模式 按住wkup键的那一瞬间会有一个上升沿 
而这个上升沿执行了唤醒功能但是没有执行外部中断0的中断服务函数 
待机模式下cpu是不工作的 从待机模式唤醒后的代码执行等同于复位后的
执行所以程序又会从头开始执行(这句话很重要) 然后又会执行到 Check_up()
函数检测 如果按住键盘的时间没有超过3s 还是会处于待机模式 加入超过了3s 
返回值为1 条件不成立 就会切换到正常运行模式 所以结论就是外部中断0的中
断服务程序在待机模式切换到正常运行模式的时候从始至终是不会运行的

记住:唤醒中只是说需要上升沿、、并没有说要进入中断*/

and so:

  1. If it is normal operation, execute the interrupt program first, judge whether it is 3 seconds, and decide whether to stand by.
  2. If it is in the standby state, first reset and initialize, judge whether it is 3 seconds, and decide whether to turn on.

Aha! I don’t know how you understand what you see here? I’m also a beginner, try to use what I understand to help you understand, and use a style that I think is humorous, and it won’t appear so rigid. Hope everyone Forgive me, beginners will inevitably have misunderstandings or do not understand or speak incompletely, so please forgive me for any mistakes here. I spent another afternoon finishing my thoughts and writing this blog. I was a little hungry. Oh, aha, I hope I can help you guys, thank you!

Guess you like

Origin blog.csdn.net/qq_39400113/article/details/109130320