本章參考資料: 《stm32f10x-中文參考手冊》 gpio 章節和 rcc 章節。
雖然我們上面用暫存器點亮了 led,乍看一下好像**也很簡單,但是我們別僥倖以後就可以一直用暫存器開發。在用暫存器點亮 led 的時候,我們會發現 stm32 的暫存器都是 32 位的,每次配置的時候都要對照著《stm32f10x-中文參考手冊》中暫存器的說明,然後根據說明對每個控制的暫存器位寫入特定引數,因此在配置的時候非常容易出錯,而且**還很不好理解,不便於維護。所以學習 stm32 最好的方法是用韌體庫,然後在韌體庫的基礎上了解底層,學習暫存器。
函式庫可以使開發人員脫離暫存器操作,當我們呼叫庫api時不需要去了解底層的暫存器操作,實際上函式庫是在暫存器和使用者驅動層之間的**,向下處理與暫存器直接相關的配置,向上提供配置暫存器的介面,庫開發與暫存器開發方式的區別如圖:
在以前 8 位機時代的程式開發中, 一般直接配置晶元的暫存器,控制晶元的工作方式,如中斷,定時器等。配置的時候,常常要查閱暫存器表,看用到哪些配置位,為了配置某
功能,該置 1 還是置 0。這些都是很瑣碎的、機械的工作,因為 8 位機的軟體相對來說較簡單,而且資源很有限,所以可以直接配置暫存器的方式來開發。
對於stm32,因為外設資源豐富,帶來的必定是暫存器的數量和複雜度的增加,這是直接配置暫存器存在很大缺陷。
這些缺陷直接影響了開發效率,程式維護成本,交流成本。庫開發方式則正好彌補了這些缺陷。而堅持採用直接配置暫存器的方式開發的程式設計師,會列舉以下原因:
相對於庫開發的方式,直接配置暫存器方式生成的**量的確會少一點,但因為stm32 有充足的資源,權衡庫的優勢與不足,絕大部分時候,我們願意犧牲一點 cpu 資源,選擇庫開發。一般只有在對**執行時間要求極苛刻的地方,才用直接配置暫存器的方式代替,如頻繁呼叫的中斷服務函式。
接下來,我們在暫存器點亮 led 的**上繼續完善,把**一層層封裝,實現庫的最初的雛形,相信經過這一步的學習後,您對庫的運用會游刃有餘。這裡我們只講如何實現gpio 函式庫,其他外設的我們直接參考 st 標準庫學習即可,不必自己寫。下面請開啟本章配套例程「構建庫函式雛形」來閱讀理解,該例程是在上一章的基礎上修改得來的。
9.3.1 外設暫存器的結構體定義
在前面中我們操作的的暫存器都是操作絕對位址,如果每乙個暫存器我們都這樣子去操作會非常麻煩,因為外設暫存器的位址都是基於外設基位址的偏移位址,都是基於外設基位址的基礎上連續遞增,每乙個暫存器佔32位,這種方式與結構體裡面的成員相似,所以我們可以定義乙個結構體,結構體的位址等於外設的基位址,結構體的成員相當於暫存器,成員的排列順序也和暫存器的排列順序一樣,這樣我們就不用每次都找到絕對位址,只需要知道暫存器的基位址就可以操作外設的全部暫存器,即操作結構體裡面的成員即可。
在「stm32f10x.h」檔案中,我們使用了結構體封裝gpio和rcc的外設暫存器,結構體成員的順序按照暫存器的偏移位址從低到高,成員型別跟暫存器型別一樣。
「volatile」關鍵字表示這個變數是易變的,要求編譯器不要優化,這些結構體的成員,都代表暫存器,而暫存器很多時候是由外設或者stm32晶元狀態是修改的,就是說即使cpu不執行**修改這些變數,變數的值也會被外設修改,所以每次使用這些變數時,我們都要求cpu去該變數的位址重新訪問。如果沒有這個關鍵字,在某些情況下,編譯器會認為沒有**修改該變數,就直接從 cpu 的某個快取獲取該變數值,這時可以加快執行速度,但該快取中的是陳舊資料,與我們要求的暫存器最新狀態可能會有出入。
學習型紅外遙控的實現 stm32
最近在做乙個智慧型家居的專案,其核心部分是使用紅外遙控各種家電,包括電視,風扇,空調等等。在製作學習型紅外遙控的過程中,遇到了許多問題,也頗有感悟,特此記錄下來與大家分享。紅外線傳送不同於一般的資料傳輸協議,在此與串列埠比較說明。串列埠是最簡單的資料傳輸協議,學過微控制器的人都知道,微控制器通過串列...
STM32學習筆記
剛到公司實習,要學習stm32開發,boss給了一塊戰艦開發板,讓我自己寫乙個功能要用在公司的產品上。難啊。以前根本沒接觸過stm32,只能一步一步慢慢來,利用晚上利用週末惡補一下。哎,算是為了大學前兩年還債吧。一 跑馬燈實驗 gpio輸出 實驗環境 keil4 實驗平台 戰艦stm32開發板 gp...
stm32學習筆記
開漏模式輸出 輸出暫存器上的 0 啟用 n mos,而輸出暫存器上的 1 將埠 置於高阻狀態 p mos從 被啟用 推挽模式輸出 輸出暫存器上的 0 啟用 n mos,而輸出暫存器上的 1 將啟用 p mos。上拉輸入 輸入高電平,然後接乙個 上拉電阻 保護作用 讀取此時的引腳電平為高電平 下拉輸入...