關於stm32單片機低功耗的實現和喚醒


最近做的項目中要求低功耗,在單片機完成了手頭上的工作之后,就進入低功耗模式,項目的需求是單片機進入低功耗模式的時候系統時鍾從HSE切到HSI,但是在未進入低功耗模式之前引腳是什么狀態,進入低功耗模式之后也不應該改變。可以通過RTC定時喚醒,或者接收到串口數據就喚醒,處理完數據后再進入stop模式。查詢了一些資料之后,發現stop模式最符合項目需求。下面講述一下什么是低功耗:

一、stm32支持三種低功耗模式,可以在低功耗,短啟動,多種喚醒模式下尋找平衡。

1、SleepMode睡眠模式,只有CPU停止運行,所有的外設處於工作狀態並且可以在發生中斷/事件時喚醒CPU。

2、StopMode停機模式,保持SRAM和寄存器內容不丟失,達到最低的電能消耗。停止所有內部1.8V部分的供電, PLL、 HSI的RC振盪器和HSE晶體振盪器被關閉,調壓器可以被置於普通模式或低功耗模式。可以通過任一EXTI從停機模式中喚醒, EXTI信號可以是16個外部I/O口之一、 PVD的輸出、 RTC鬧鍾或USB的喚醒信號。

3、StandbyMode待機模式。最低的電能消耗。內部1.8V部分的供電被切斷; PLL、 HSI的RC振盪器和HSE晶體振盪器關閉;SRAM和寄存器的內容將消失,但后備寄存器的內容仍然保留,待機電路仍工作。從待機模式退出的條件是: NRST上的外部復位信號、 IWDG復位、 WKUP引腳上的一個上升邊沿或RTC的鬧鍾到時。

二、低功耗模式基於HAL庫的常用API

2.1睡眠模式SleepMode

  • __HAL_RCC_PWR_CLK_ENABLE();//電源管理使能
  • HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);//進入睡眠模式

2.2停機模式StopMode

  • __HAL_RCC_PWR_CLK_ENABLE();//電源管理使能
  • HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);//進入停機模式

2.3 待機模式StandbyMode

  • __HAL_RCC_PWR_CLK_ENABLE();//電源管理使能
  • PWR_Check_Standby();//檢查是否是待機模式
  • __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//清除喚醒標志
  • __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);//清除待機標志
  • __HAL_PWR_GET_FLAG(PWR_FLAG_SB);//獲得待機模式標志
  • HAL_PWR_EnterSTANDBYMode();//進入待機模式

以上相關描述參考https://blog.csdn.net/u010058695/article/details/100008613

三、Stop模式中遇到的一些問題及解決方法

1、沒有配置好喚醒機制,導致進入stop模式后沒能喚醒,導致無法識別到st-link,無法重新燒錄程序。即使重新上電也不能識別到st-link。

我在這個問題上栽了跟頭,因為單片機重新上電后依然不能識別到st-link,所以以為是單片機壞了,重新換了單片機再燒錄同樣的程序,結果問題還是一樣,我開始意識到問題不是那么簡單,上網找了一下資料,才知道是進入stop模式后不能喚醒,具體的做法有幾種:

①  可以將單片機的NRST引腳引出來,外接復位鍵。(關於引腳查看可用ST官方軟件STM32cubeMX,很方便)如圖:把NRST引出來通過一個按鍵連接到GND,當進入STOP模式不能燒錄程序的時候只需要在按下按鍵后,點擊keil的,然后松手即可。

 

 

 

②  通過ISP的方式下載程序,必須將boot0接高電平,boot1(PB2)接低電平,然后必須斷電后重啟,此時單片機會進入ISP模式,就可以通過串口1(一般單片機都是只有串口1才可下載程序)再用flymcu等軟件燒入hex文件就可以了。

關於boot0和boot1,在每個stm32單片機都會有這兩個引腳,這兩個引腳在復位時的電平狀態決定了芯片在復位后從哪個區域開始執行程序。

  boot1=x boot0=0從用戶閃存啟動,這是正常的工作模式。

  boot1=0 boot0=1從系統存儲器啟動(進入ISP模式)。

  boot1=1 boot0=1從內置SRAM啟動,這種模式可以用於調試。

  如此一來,單片機無法進入正常的工作模式,就無法進行休眠,就可以通過ISP來下載程序。

③  使用STlink燒寫程序,STlink至少要接4根線(SWDIO、SWCLK、GND、SW-RST),一般的下載程序只需要前三根就可以了,但是以防出現休眠無法喚醒的情況,這時有復位鍵就可以將SWDIO和SWCLK重置,如果板子設計沒有與SW-RST相對應的,此時需要把單片機上的NRST引出來接到SW-RST上。下載程序之前boot0接高電平,boot1不用管(也需要斷電后重啟)。

下載配置這里按如下配置,RESET那里HW RESET和SYSRESETREQ任選一個。

配置好之后load一個空程序即可,不要再燒一個休眠的程序了,之后就可以正常燒程序了。

以上解決方法參考https://blog.csdn.net/geekjin/article/details/79232405,總結就是復位NRST這個引腳是最簡單的方法,以后做項目還是要提醒硬件工程師把這個引腳引出來。

2、項目需要單片機在進入stop 模式后過5秒鍾就喚醒,實際上RTC鬧鍾中斷也是掛在EXTI中斷上的。我是用CubeMX配置的RTC,但是一直沒有喚醒,后面終於找到問題所在了:

 

 紅色框框里的前三個應該配置為Enable,第四個應該配置為Disable,前三個是鬧鍾屏蔽星期,鬧鍾屏蔽小時,鬧鍾屏蔽分鍾,如果不是這樣配置的話,只能等到時間達到了設定好的某天某時某分某秒才能發生中斷,那么只能一周喚醒一次了。如果是這樣設置的話,就是一分鍾喚醒一次,那么怎么才能5秒鍾喚醒一次呢?我的做法是每次進入stop模式前就調用一次MX_RTC_Init()函數一次,因為我的時間是設置為x年x月x日星期x x時x分0秒,所以相當於每次進入stop模式前初始化一次RTC,5秒鍾后就會發生鬧鍾中斷。這種辦法可能是比較笨的方法,但是好歹實現了這個功能哈哈

3、為了方便調試,我還配置了LED,每隔200ms閃爍一次,但是我發現從stop模式喚醒后燈的閃爍明顯變得很慢,而且串口數據的接收和發送也不能完成,這是為什么呢?

  原來進入stop模式后系統時鍾默認切換到內部8M時鍾,所以頻率就會變慢了

 

 

  我的解決方法是重新配置系統時鍾:

/**************************************
*函數名稱:void SYSCLKConfig_STOP(void)
*函數功能:選擇HSE作為時鍾源
*函數形參:無
*函數返回值:無
****************************************/
void SYSCLKConfig_STOP(void)
{
	__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
	
	while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
	{
	}
	
	 /* 使能 PLL */
  __HAL_RCC_PLL_ENABLE();

  /* 等待 PLL 准備就緒 */
  while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
  {
  }

  /* 選擇PLL作為系統時鍾源 */
  __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);

  /* 等待PLL被選擇為系統時鍾源 */
  while(__HAL_RCC_GET_SYSCLK_SOURCE() != 0x08)
  {
  }
}

4、接收到串口數據后怎么喚醒stop模式?

   其實RTC鬧鍾中斷喚醒stop模式也是因為鬧鍾事件是連接着外部中斷線的,但是串口接收中斷並不能喚醒stop模式啊,怎么辦?

 

 解決方法有兩種,一種是在RX引腳上接上光耦連接到其他IO口上,把該IO口配置為外部中斷,但是這種方案比較麻煩,所以可以采取第二種方案,在進入stop模式之前把RX引腳配置為外部中斷模式,這樣的話,RX引腳上有電平變化的時候就會發生外部中斷,在服務函數中記得把RX引腳再配置為復用為UART的接收引腳。並且重新配置系統時鍾,選擇HSE為時鍾源。這樣就可以實現喚醒並接收數據了。但是因為第一次接收到串口數據的時候只能喚醒stop模式,並不能接收到數據,所以應該跟發送方約定好,一幀數據要發送兩次。而且中間要有一定間隔,我的間隔是500ms。這樣確實比較麻煩,但是暫時沒有更好的辦法。

5、串口接收引腳配置為外部中斷引腳后還是沒有正常接收到數據。在喚醒后延時1秒鍾就可以接收到數據。

  這是因為stop模式喚醒后,因為沒有延時,很快又進入stop模式,這個時候第二幀數據還沒到來,等到第二幀數據到來的時候處於stop模式中,這幀數據只能起到喚醒的作用,很快又進入了stop模式,變成一個惡性循環。

 

以上就是我對stop模式和喚醒的總結,不正確的地方請大家斧正!

  


免責聲明!

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



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