STM32的待機喚醒實(shí)驗分析(基于原子哥程序)

發(fā)布時(shí)間:2016-10-20 15:36    發(fā)布者:designapp
關(guān)鍵詞: STM32 , 待機喚醒
  前段時(shí)間我稍微涉及節能減排大賽、、倡導節能的社會(huì )、、沒(méi)錯了、你真是太聰明了、、知道了我今天要講關(guān)于STM32節能方面的模塊、、沒(méi)錯、、這標題已經(jīng)告訴你了是吧、、哦,對,標題有寫(xiě)、、所以、、言歸正傳、至于STM32如何達到節能的、、語(yǔ)文老師說(shuō)要留下懸念、、跟著(zhù)作者走下去、、也就是跟我啦、、
  大家翻開(kāi)STM32的中文參考手冊(你們看就行了,我翻,然后截圖),里面關(guān)于STM32的低功耗模式有詳細的標注,突然不想截圖。。
  1、睡眠模式(Cortex?-M3內核停止,所有外設包括Cortex-M3核心的外設,如NVIC、系統時(shí)鐘(SysTick)等仍在運行)
  2、停止模式(所有的時(shí)鐘都已停止)
  3、待機模式(1.8V電源關(guān)閉)(我們本博客中具體介紹的一種模式,也是功耗最低的模式)
  現附上三者照片、、望觀(guān)眾好好欣賞、、還有請稍微注意下我的涂鴉、、小弟感激不盡:
  


  啊哈、、這照片是不是很神奇呀、、即把三個(gè)老家伙的家底進(jìn)行了較為認真的比較,而且從照片中我們也可以看出,如何進(jìn)入,如何喚醒他們、、而且有什么影響都跟我們透露了、、可謂是后生可畏呀、、所以我叫大家注意我美麗的涂鴉是有道理的、、哈、
  在本博客中,我們就利用WKUP引腳的上升沿來(lái)喚醒MCU、、不好意思哈、、老是把上升沿打成上小沈陽(yáng)、、所以我們就具體來(lái)介紹待機喚醒的實(shí)現方法、、
  那我們要怎么來(lái)進(jìn)入待機模式、、又要怎么喚醒呢?
  


  看到“進(jìn)入”中的紅色數字標號了吧、、沒(méi)錯了、、我們只要按照此步驟來(lái)設置相應的寄存器就行了、、那、、我打???的是什么呢??好了、、請容許我介紹下:
  1、 Cotex_M3系統控制寄存器中的SLEEPDEEP位到底在哪呢??大家請翻開(kāi)《權威指南》第182頁(yè)可以看到表格、、當然這里不用你翻開(kāi)、、因為我已截圖:
  


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


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


  至此、我們通過(guò)這三步、完成了進(jìn)入待機模式的任務(wù)、、那我們怎么通過(guò)程序實(shí)現呢?啊哈、、庫神出現吧、、:::系統出現奔潰、、請稍后、、詳情請咨詢(xún)10086、、
  額、、出現了點(diǎn)意外、、不急哈、、那我們先來(lái)看看怎么退出待機模式:重現一張圖片:
  


  看到了吧、、在這里我們就利用其中一種方式來(lái)喚醒:WKUP引腳的上升沿、、注意哈、、注意此上升沿三個(gè)字哈、、 至于為什么要注意上升沿、、在這里提出我也是有目的、、先記著(zhù)哈、、你此時(shí)想的為什么要注意的原因肯定跟我待會(huì )提到的時(shí)候不一樣、、在此先奸笑下、、
  那我們要怎么來(lái)喚醒呢??
  親、、我們通過(guò)外部中斷觸發(fā)來(lái)喚醒、、所以請看代碼:
  1 void Wkup_Init(void)
  2 {
  7 EXTI_InitTypeDef EXTI_InitStructure;
  8 NVIC_InitTypeDef NVIC_InitStructure;
  9
  10 KEY_Init();//我的IO初始化在按鍵里已經(jīng)初始化了
  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) //系統初始化后由于沒(méi)有按下按鍵、、所以系統直接進(jìn)入了待機模式了,所以下載了程序沒(méi)有任何反應、、需要人為的喚醒:死豬,就知道睡,快醒、、
  29 {
  30 Sys_Standby(); //進(jìn)入待機模式
  31 }
  32 }
  復制代碼
  復制代碼
  //正常模式下會(huì )運行中斷服務(wù)函數,而待機模式下則不會(huì )運行中斷服務(wù)函數、、因為待機模式下MCU不工作,所以上升沿的作用也僅僅是喚醒、、
  //在這里提醒:?jiǎn)拘阎恍枰仙、、所以從待機模式切換到正常模式下從始至終都不會(huì )執行中斷服務(wù)函數
  //在這里,知道我為什么要在上面提醒大家要注意上升沿了吧、(下面還有)、
  //至于為什么不會(huì )執行,待會(huì )我還會(huì )給出解釋、、
  3 void EXTI0_IRQHandler(void)
  4 {
  5 EXTI_ClearITPendingBit(EXTI_Line0);
  6 if(Check_up())
  7 {
  8 Sys_Enter_Standby();
  9 }
  10 }
                                
                                                               
                                
                  看到以上代碼會(huì )不會(huì )熟悉呢??在這里就不解釋了哈、、所以重點(diǎn)來(lái)講講步驟
  1、使能PWR的時(shí)鐘:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  2 、使能喚醒的功能:PWR_WakeUpPinCmd(ENABLE);
  3、進(jìn)入待機模式 : PWR_EnterSTANDBYMode();
  請看代碼:
  void Sys_Standby(void) //在喚醒初始化中調用
  {
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  PWR_WakeUpPinCmd(ENABLE);
  PWR_EnterSTANDBYMode();
  }
  void Sys_Enter_Standby(void)//在中斷函數里調用,用來(lái)復位,然后進(jìn)入待機模式
  {
  RCC_APB2PeriphResetCmd(0X01FC,DISABLE); //在這里只是復位了IO口、、至于0x01fc是怎么來(lái)的、、大家請看RCC_APB2RSTR(下圖)
  Sys_Standby();
  }
  


  最后我們給出按鍵檢測的處理程序、、在這里,3S只是一個(gè)效果、、也可以不用、、也可以長(cháng)點(diǎn)、、看你個(gè)人哈(原子的程序,別告我盜版哈)
  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; //錯誤按鍵或者按鍵時(shí)間不夠
  }
  }
  delay_ms(30);
  if(t > 100) //100*30ms = 3s
  {
  LED0 = 0;
  return 1;// 3s
  }
  }
  }
  看到這里、、可能有人會(huì )有些搞不懂在中斷服務(wù)函數那里的邏輯、、在這里我給出解釋哈:
  從正常運行模式切換到待機模式 按住wkup鍵 外部中斷0中斷被觸發(fā) 執行中斷服務(wù)函數 Check_up()函數開(kāi)始檢測 如果時(shí)間沒(méi)超過(guò)3s 返回零 這時(shí)工作在正常運行模式 如果按住時(shí)間超過(guò)了3s 返回值為1 進(jìn)入待機模式
  我們的程序在剛開(kāi)始運行時(shí)就是沒(méi)有按鍵按下、、所以沒(méi)有上升沿,初始化函數里條件成立,從而進(jìn)入了待機模式:請看初始化的代碼:
  if (Check_up() == 0)
  29 {
  30 Sys_Standby(); //進(jìn)入待機模式
  31 }
  從待機模式切換到正常運行模式 按住wkup鍵的那一瞬間會(huì )有一個(gè)上升沿 而這個(gè)上升沿執行了喚醒功能但是沒(méi)有執行外部中斷0的中斷服務(wù)函數 待機模式下cpu是不工作的 從待機模式喚醒后的代碼執行等同于復位后的執行所以程序又會(huì )從頭開(kāi)始執行(這句話(huà)很重要) 然后又會(huì )執行到 Check_up()函數檢測 如果按住鍵盤(pán)的時(shí)間沒(méi)有超過(guò)3s 還是會(huì )處于待機模式 加入超過(guò)了3s 返回值為1 條件不成立 就會(huì )切換到正常運行模式 所以結論就是外部中斷0的中斷服務(wù)程序在待機模式切換到正常運行模式的時(shí)候從始至終是不會(huì )運行的
  記。?jiǎn)拘阎兄皇钦f(shuō)需要上升沿、、并沒(méi)有說(shuō)要進(jìn)入中斷
  所以:
  1 、如果是正常運行,先執行中斷程序,判斷是否3秒,決定是否待機。
  2 、如果是待機狀態(tài),則先復位并初始化,判斷是否3秒,決定是否開(kāi)機。
  啊哈、、不知看到這里的你理解得怎么樣了、、我也是初學(xué)者,盡量用我所理解的來(lái)幫助你們理解、、用點(diǎn)自認為是幽默的風(fēng)格來(lái)、、不會(huì )顯得那么的死板、、希望大家見(jiàn)諒哈、、初學(xué)者難免有理解上的失誤或者不懂或者講得不全面、、所以在這有寫(xiě)錯的敬請原諒哈、、
本文地址:http://selenalain.com/thread-176538-1-1.html     【打印本頁(yè)】

本站部分文章為轉載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀(guān)點(diǎn)和對其真實(shí)性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問(wèn)題,我們將根據著(zhù)作權人的要求,第一時(shí)間更正或刪除。
潘瑋柏 發(fā)表于 2016-10-25 00:15:54
厲害啊。我的哥
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页