STM32之待機喚醒


    前段時間我稍微涉及節能減排大賽、、倡導節能的社會、、沒錯了、你真是太聰明了、、知道了我今天要講關於STM32節能方面的模塊、、沒錯、、這標題已經告訴你了是吧、、哦,對,標題有寫、、所以、、言歸正傳、至於STM32如何達到節能的、、語文老師說要留下懸念、、跟着作者走下去、、也就是跟我啦、、

    大家翻開STM32的中文參考手冊(你們看就行了,我翻,然后截圖),里面關於STM32的低功耗模式有詳細的標注,突然不想截圖。。

       1、睡眠模式(Cortex™-M3內核停止,所有外設包括Cortex-M3核心的外設,如NVIC、系統時鍾(SysTick)等仍在運行)

       2、停止模式(所有的時鍾都已停止)

       3、待機模式(1.8V電源關閉)(我們本博客中具體介紹的一種模式,也是功耗最低的模式

  現附上三者照片、、望觀眾好好欣賞、、還有請稍微注意下我的塗鴉、、小弟感激不盡:

 

    啊哈、、這照片是不是很神奇呀、、即把三個老家伙的家底進行了較為認真的比較,而且從照片中我們也可以看出,如何進入,如何喚醒他們、、而且有什么影響都跟我們透露了、、可謂是后生可畏呀、、所以我叫大家注意我美麗的塗鴉是有道理的、、哈、

    在本博客中,我們就利用WKUP引腳的上升沿來喚醒MCU、、不好意思哈、、老是把上升沿打成上小沈陽、、所以我們就具體來介紹待機喚醒的實現方法、、

    那我們要怎么來進入待機模式、、又要怎么喚醒呢?

    

   看到“進入”中的紅色數字標號了吧、、沒錯了、、我們只要按照此步驟來設置相應的寄存器就行了、、那、、我打???的是什么呢??好了、、請容許我介紹下:

        1、 Cotex_M3系統控制寄存器中的SLEEPDEEP位到底在哪呢??大家請翻開《權威指南》第182頁可以看到表格、、當然這里不用你翻開、、因為我已截圖:

  

     2、電源控制寄存器(PWR_CR)中PDDS位:請看寄存器的位:

     

   3、電源控制/狀態寄存器(PWR_CSR)中EWUP位

 

   至此、我們通過這三步、完成了進入待機模式的任務、、那我們怎么通過程序實現呢?啊哈、、庫神出現吧、、:::系統出現奔潰、、請稍后、、詳情請咨詢10086、、

  額、、出現了點意外、、不急哈、、那我們先來看看怎么退出待機模式:重現一張圖片:

 

    看到了吧、、在這里我們就利用其中一種方式來喚醒: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 }

     看到以上代碼會不會熟悉呢??在這里就不解釋了哈、、所以重點來講講步驟

  1、使能PWR的時鍾:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

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

  3、進入待機模式 : 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秒,決定是否開機。

 

    啊哈、、不知看到這里的你理解得怎么樣了、、我也是初學者,盡量用我所理解的來幫助你們理解、、用點自認為是幽默的風格來、、不會顯得那么的死板、、希望大家見諒哈、、初學者難免有理解上的失誤或者不懂或者講得不全面、、所以在這有寫錯的敬請原諒哈、、又花了一下午的時間整理思路寫了這篇博客、、肚子有點餓了、、啊哈、、希望能幫到你們哈、、謝謝、、

    

   附加題:當你看到“小心地滑”的標語時,請別誤會成 :為什么我不能勇敢地滑,而要小心地滑、、這下子你應該會明白為什么當初語文考試要你做文言文斷句了、、好好找亮點吧、找到亮點后好好的笑笑、然后好好的生活、發現更多的亮點、讓生活多充滿自我娛樂的樂趣、然后繼續努力、、生活依舊美好、、


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM