STM32之待机唤醒

    前段时间我稍微涉及节能减排大赛、、倡导节能的社会、、没错了、你真是太聪明了、、知道了我今天要讲关于STM32节能方面的模块、、没错、、这标题已经告诉你了是吧、、哦,对,标题有写、、因此、、言归正传、至于STM32如何达到节能的、、语文老师说要留下悬念、、跟着做者走下去、、也就是跟我啦、、函数

    你们翻开STM32的中文参考手册(大家看就好了,我翻,而后截图),里面关于STM32的低功耗模式有详细的标注,忽然不想截图。。spa

       一、睡眠模式(Cortex™-M3内核中止,全部外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行)3d

       二、中止模式(全部的时钟都已中止)code

       三、待机模式(1.8V电源关闭)(咱们本博客中具体介绍的一种模式,也是功耗最低的模式blog

  现附上三者照片、、望观众好好欣赏、、还有请稍微注意下个人涂鸦、、小弟感激涕零:图片

 

    啊哈、、这照片是否是很神奇呀、、即把三个老家伙的家底进行了较为认真的比较,并且从照片中咱们也能够看出,如何进入,如何唤醒他们、、并且有什么影响都跟咱们透露了、、可谓是后生可畏呀、、因此我叫你们注意我美丽的涂鸦是有道理的、、哈、ip

    在本博客中,咱们就利用WKUP引脚的上升沿来唤醒MCU、、很差意思哈、、总是把上升沿打成上小沈阳、、因此咱们就具体来介绍待机唤醒的实现方法、、博客

    那咱们要怎么来进入待机模式、、又要怎么唤醒呢?it

    

   看到“进入”中的红色数字标号了吧、、没错了、、咱们只要按照此步骤来设置相应的寄存器就好了、、那、、我打???的是什么呢??好了、、请允许我介绍下:io

        一、 Cotex_M3系统控制寄存器中的SLEEPDEEP位到底在哪呢??你们请翻开《权威指南》第182页能够看到表格、、固然这里不用你翻开、、由于我已截图:

  

     二、电源控制寄存器(PWR_CR)中PDDS位:请看寄存器的位:

     

   三、电源控制/状态寄存器(PWR_CSR)中EWUP位

 

   至此、咱们经过这三步、完成了进入待机模式的任务、、那咱们怎么经过程序实现呢?啊哈、、库神出现吧、、:::系统出现奔溃、、请稍后、、详情请咨询1008六、、

  额、、出现了点意外、、不急哈、、那咱们先来看看怎么退出待机模式:重现一张图片:

 

    看到了吧、、在这里咱们就利用其中一种方式来唤醒:WKUP引脚的上升沿、、注意哈、、注意此上升沿三个字哈、、 至于为何要注意上升沿、、在这里提出我也是有目的、、先记着哈、、你此时想的为何要注意的缘由确定跟我待会提到的时候不同、、在此先奸笑下、、

    那咱们要怎么来唤醒呢??

    亲、、咱们经过外部中断触发来唤醒、、因此请看代码:  

 1 void Wkup_Init(void)
 2 {   
 7     EXTI_InitTypeDef EXTI_InitStructure;
 8       NVIC_InitTypeDef NVIC_InitStructure;
 9     
10       KEY_Init();//个人IO初始化在按键里已经初始化了
11     
12       RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); 
13     
14       GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
15     
16         EXTI_InitStructure.EXTI_Line = EXTI_Line0; //PA0        
17         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
18         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;   
19         EXTI_InitStructure.EXTI_LineCmd = ENABLE;
20         EXTI_Init(&EXTI_InitStructure);
21     
22         NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   
23         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
24         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
25         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
26         NVIC_Init(&NVIC_InitStructure);   
27         
28       if(Check_up() == 0)   //系统初始化后因为没有按下按键、、因此系统直接进入了待机模式了,因此下载了程序没有任何反应、、须要人为的唤醒:死猪,就知道睡,快醒、、 29         {
30           Sys_Standby();         //进入待机模式
31         }      
32 }
//正常模式下会运行中断服务函数,而待机模式下则不会运行中断服务函数、、由于待机模式下MCU不工做,因此上升沿的做用也仅仅是唤醒、、
//在这里提醒:唤醒只须要上升沿、、因此从待机模式切换到正常模式下从始至终都不会执行中断服务函数
//在这里,知道我为何要在上面提醒你们要注意上升沿了吧、(下面还有)、
//至于为何不会执行,待会我还会给出解释、、
3
void EXTI0_IRQHandler(void) 4 { 5 EXTI_ClearITPendingBit(EXTI_Line0); 6 if(Check_up()) 7 { 8 Sys_Enter_Standby(); 9 } 10 }

     看到以上代码会不会熟悉呢??在这里就不解释了哈、、因此重点来说讲步骤

  一、使能PWR的时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  2 、使能唤醒的功能:PWR_WakeUpPinCmd(ENABLE);

  三、进入待机模式 : PWR_EnterSTANDBYMode();

请看代码:

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();
}

最后咱们给出按键检测的处理程序、、在这里,3S只是一个效果、、也能够不用、、也能够长点、、看你我的哈(原子的程序,别告我盗版哈)

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
        }
    }
}

    看到这里、、可能有人会有些搞不懂在中断服务函数那里的逻辑、、在这里我给出解释哈:

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

记住:唤醒中只是说须要上升沿、、并无说要进入中断

    因此:

   1 、若是是正常运行,先执行中断程序,判断是否3秒,决定是否待机。  
   2 、若是是待机状态,则先复位并初始化,判断是否3秒,决定是否开机。

 

    啊哈、、不知看到这里的你理解得怎么样了、、我也是初学者,尽可能用我所理解的来帮助大家理解、、用点自认为是幽默的风格来、、不会显得那么的死板、、但愿你们见谅哈、、初学者不免有理解上的失误或者不懂或者讲得不全面、、因此在这有写错的敬请原谅哈、、又花了一下午的时间整理思路写了这篇博客、、肚子有点饿了、、啊哈、、但愿能帮到大家哈、、谢谢、、

    

   附加题:当你看到“当心地滑”的标语时,请别误会成 :为何我不能勇敢地滑,而要当心地滑、、这下子你应该会明白为何当初语文考试要你作文言文断句了、、好好找亮点吧、找到亮点后好好的笑笑、而后好好的生活、发现更多的亮点、让生活多充满自我娱乐的乐趣、而后继续努力、、生活依旧美好、、

相关文章
相关标签/搜索