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秒,決定是否開機。

 

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

    

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

相關文章
相關標籤/搜索