我們知道,STM32芯片里有很多系統級的復位,比方上電復位、欠壓復位、看門狗復位、軟件復位、復位腳電平觸發復位等等。這些系統級的復位往往都是針對整個芯片或芯片的絕大部分區域。
其實,我們在實際應用中有時候可能并不需要、甚至不接受總是對整個芯片做大面積的復位。正因為如此,STM32的芯片里除了具備那些系統級復位功能外,還針對各個外設設計了復位功能,即我們可以只需針對某特定外設或特定區域做復位而不影響其它。特定區域一般是指某一塊總線驅動的外設集,比方掛在APB1總線的所有外設。
或許有人不了解、或者說沒有使用過針對特定外設復位的功能,這里就簡單介紹下,拋磚引玉。在STM32各個系列的參考手冊里的RCC章節,有關于對外設或局部外設集進行復位的介紹。類似下圖所示信息:
結合上面截圖內容,我們可以針對性地對某個特定外設做強制復位及復位釋放。在ST提供的外設固件庫里也有相應的函數可以調用。比方HAL庫里面就是類似下面這些的代碼【不同版本寫法或許略有差異】:
從上面截圖里的代碼不難看出,針對某個外設的復位和釋放代碼都是成對地寫好了的。那么,針對STM32外設做復位,一般用在哪些場合呢。我這里稍微總結了下,大致有下面三種情況供參考使用。
一、撥亂反正,歸零再來
在具體應用中,難免可能出現某特定外設工作異常的情形,這時,我們可以嘗試對該外設做強制復位,然后重新配置后啟動運行。比方說,我們在使用I2C硬件模式時,有時會碰到I2C總是出現busy狀態,這時我們可以嘗試對I2C外設做個強制復位,然后再做后續配置。
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
再比如,有時可能碰到芯片外部LSE工作不穩定,除了排查其它因素外,我們還可以嘗試在配置系統時鐘前對RTC域先做強制復位操作。
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
總之,某外設工作途中出現異常,對其進行強制復位,這樣我們可以不受那些不清晰或不確定的狀態干擾,再做配置后重新運行也是比較常見的應對問題的一種做法。
二、改頭換面,重拾使命
在程序運行過程中,我們有時需要對外設做參數或功能的變動,這時對外設做針對性地強制復位就很有必要。其中有些參數或狀態的改變本身就要求對外設做復位。比方,有些寄存器是帶LOCK功能的,當設置LOCK位后,若要消除LOCK功能,往往需要對該外設做復位操作,【此時顯然也沒必要來個系統級復位】。又比方,RTC的時鐘切換也是需要對RTC域復位的,否則你變更不了。
當然,更為常見的是,我們經常會在代碼中根據時間或事件的變化而變更外設的功能及參數,需要重新配置外設。這時來個快刀斬亂麻,對外設先做個強制復位再做配置就非常簡單清爽。
比方前不久有人問起一個CAN應用方面的問題。 他開始是基于回環模式對CAN進行測試,然后想切換到Normal模式。令他費解的是,怎么也切換不過去,除非做模式切換配置之前加入下面這段代碼:
上面代碼的主要功能就是對CAN1做強制復位。因為這是ST早期標準庫的代碼,所以代碼寫法上跟我前面貼出來的很不一樣,但功能一樣??蛻魧ι厦鎯尚写a的功能理解有誤,以為是對CAN1外設的時鐘進行開啟和關閉,質問此處開關時鐘操作的意義何在,很是覺得匪夷所思。不難理解,先行對CAN1做強制復位,讓所有狀態先回歸到默認初始狀態【Default state after reset】,然后再做新的配置,就不會受到之前回環模式下的那些配置的牽牽絆絆了,做起狀態切換來自然是順山順水。
三、節能減排,錦上添花
在涉及到STM32芯片低功耗應用時,在進入低功耗模式前,我們除了做些常規的動作外,比如關閉相應外設的運行、處理不用的或跟外界有連接的GPIO等。如果在進入低功耗模式前,對剛才使用過的外設,先來個強制復位,有時或許會給你帶來意想不到的收效。
上面我大致介紹了幾種可能用到外設復位的場景,當然也不排除還有其它場景??傊m時恰當地使用外設復位,也是我們STM32開發者可以善加利用的一個工具或手段。關于STM32外設復位,這里給兩點提醒作為結尾。
第一點,在做外設復位前,該外設的時鐘一定是開啟了的,更不要與外設時鐘的開啟和關閉相混淆。
第二點,一般來講,針對外設復位操作要求成對出現。即先做強制復位【xxx_Reset_Force】,緊接著做復位釋放【xxx_Reset_Release】。針對外設復位的代碼,在ST提供的HAL庫例程里不難看到,多封裝在xxx__MspDeInit()函數里面。
責任編輯:彭菁
-
軟件
+關注
關注
69文章
5007瀏覽量
87930 -
函數
+關注
關注
3文章
4345瀏覽量
62870 -
STM32芯片
+關注
關注
0文章
38瀏覽量
4407
發布評論請先 登錄
相關推薦
評論