如果你只有C語言基礎就馬上學習STM32,你一定會有這些疑惑:
為什麼有這麼多沒見過的API函數?沒見過的變量(寄存器)名稱?
為什麼工程除了main.c,還有這麼多其它沒見過的文件?它們有什麼用?
什麼是Flash?什麼是RAM?什麼是ROM?
什麼是寄存器?什麼是時鐘?什麼是中斷?什麼是定時器?什麼是DMA?
什麼是埠復用與重映射?什麼是ADC?什麼是PWM?什麼是UART?什麼是IIC?什麼是SPI?
什麼是原理圖?什麼是PCB?什麼是晶振?什麼是復位?什麼是電平?什麼是上拉下拉浮空?
為什麼我的helloworld c語言程序不能下載到STM32中運行?為什麼下載的固是.hex文件?.hex .bin .exe文件有什麼區別?
為什麼有寄存器編程?還有標准/HAL庫編程?甚至網上查的教程還有STM32CubeMX可視化配置編程?應該學哪種?用哪種?
如果你只有C語言基礎,你有上面這些疑惑,是非常非常正常的。因為C語言只是一門程式語言,在單片機上,你可以用彙編編程、C語言編程,甚至很多極客板卡上,你可以用Python,JavaScript編程。為什麼現在單片機編程都以C語言為主?因為各大晶片廠商,提供的BSP包都是以C為主,權衡性能效率和可維護性來說,C語言可以說是當前最優解。
所以你和STM32之間,差的就是這部分的知識點,或者換個角度說,你和單片機之間,差的就是這部分的知識點,因為對於所有的單片機,這部分的知識都是通用的。
前置:開發板的選擇
我個人是比較建議買最小系統板的,一是價格低,二是學習的時候你更容易理清每個模塊的關係,三是可以根據自己設計需要購買不同的外設模塊進行調試。
一款系統板,一個Jlink,一個串口模塊你就可以學習工程搭建,時鐘配置,定時器,GPIO,UART,USB甚至RTOS這些內容,在買個SPI小螢幕、IIC傳感器啥的,百元內完全覆蓋。
STM32F103最小系統板
一、單片機基礎知識點
關於這部分的知識點,可以參考這本書籍,通讀一遍,對這些關鍵詞有概念即可。
書籍可在公眾號下載:嵌入式思維導圖,回復「單片機」
二、單片機啟動過程
有基本的了解後,了解下單片機的啟動過程,無論那款單片機,都會有一個啟動文件,這個文件由原廠提供,通過了解啟動文件,我們可以了解到處理器的架構、指令集、中斷向量安排等內容。
啟動代碼通常都燒寫在flash中,它是系統一上電就執行的一段程序,它運行在任何用戶c代碼之前。上電後,arm處理器處於arm態,運行於管理模式,同時系統所有中斷被禁止,pc到地址0處取指令執行。一個可執行映像文件必須有個入口點,而能放在rom起始處的映像文件的入口地址也必須設置為0.在彙編語言中,我們已經說過怎樣定義一個程序的入口點,當工程中有多個入口點時,需要在連接器中使用-entry指出程序的入口點。如果用戶創建的程序中,包含了main函數,則與c庫初始化代碼對應的也會有個入口點。
總的來說,啟動代碼主要完成兩方面的工作,一是初始化執行環境,例如中斷向量表、堆棧、i/o等;二是初始化c庫和用戶應用程式。
這段文字看不懂怎麼辦?沒關係,入門時,我們只需要知道有這個東西即可。
而STM32整個啟動過程是指從上電開始,一直到運行到main函數之間的這段過程,步驟為:
上電後硬體設置SP、PC
PC:Program Counter,通用寄存器,控制程序執行,用來指向當前運行指令的下一條指令。
SP:Stack Pointer,通用寄存器,堆棧指針,用於入棧和出棧操作。
ARM微處理器共有37個32位寄存器,其中31個為通用寄存器,6個位狀態寄存器。
但是這些寄存器不能被同時訪問,具體哪些寄存器是可以訪問的,取決ARM處理器的工作狀態及具體的運行模式。
但在任何時候,通用寄存器R14~R0、程序計數器PC(即R15)、一個狀態寄存器都是可訪問的。
設置系統時鐘
軟體設置SP
加載.data、.bss,並初始化棧區
跳轉到C文件的main函數
STM32啟動過程
到這裡,終於到了我們學C語言的入口部分main,是不是熟悉多了?
所以總結來說,相比於我們之前寫C語言程序,單片機工程裡面有一部分的文件和代碼都是為上面這個啟動過程服務的,所以看不懂工程裡面的這些文件也就很正常,就入門來說,我們直接使用官方工程配置的文件即可。
三、單片機工程如何搭建
那STM32的工程是如何生成呢?傳統的視頻教程,都會教我們一個個文件新建、複製,教程的老師為什麼知道需要使用什麼文件?因為那是晶片原廠提供的,我們當然可以直接下載晶片原廠的示例庫,然後直接用上面的工程,修改main函數後的內容進行開發。
原廠資料下載看這裡:ST官網,這裡你可以找到的使用手冊、源碼、軟體工具,比任何教程資料都要完整。
這裡順便再提及一個點,我們學C語言的時候IDE用Visual C++,Visual Studio,然後學單片機的時候為什麼需要用KEIL、IAR呢?這裡就有一個交叉編譯的概念。
我們之前常見的軟體開發,都是屬於本地編譯:
在當前的PC下,x86的CPU下,直接編譯出來程序,可以運行的程序(或者庫文件),其可以直接在當前的環境,此時的
編譯,可以叫做本地編譯。
交叉編譯,是一個和,本地編譯,相對應的概念。
而所謂的,交叉編譯,就是在一種平台上編譯,編譯出來的程序,是放到別的平台上運行即編譯的環境,和運行的環境
不一樣,屬於交叉的,此所謂cross。
而KEIL MDK、IAR就是一套集合了交叉編譯工具鏈、仿真、下載工具的一個更方便開發的軟體而已。所以企業裡面使用破解KEIL的時候收到律師函就很正常了,別人做一個這麼好用的工具是要收費的。但如果你喜歡,你其實是可以在Linux上搭建自己的STM32交叉編譯工具鏈(gcc-arm-none-eabi)環境的,然後用gdb進行仿真調試,完全脫離KEIL。
然後我們回到STM32學習這個問題上,之前說了,STM32編程有三種方式:
.寄存器編程
.標准/HAL庫編程
.STM32CubeMX可視化編程
它們出現的時間是1>2>3,寄存器是最早也是最原始的,所以,我更建議的入門方法是,STM32CubeMX可視化編程的方式,這也是ST主推的一種方式,對於我們而已,這也是最容易上手的一種學習方式。
關於是否有必要從寄存器編程開始學?入門我是不建議的,學習效率太低,一種功能需要修改的數據、控制、狀態多個寄存器,各種與或非移位操作,一旦看錯一個位,排查困難,而且代碼維護也非常困難,必須對著幾百幾千頁的晶片手冊,一個一個看。也正是因為寄存器開發效率太低,所以ST才封裝了標準庫和HAL庫,而STM32CubeMX可視化編程的出現,則是因為HAL庫的配置不直觀,就像你配置一個外設時鐘,你得各種計算,而CubeMX,一張圖即可非常清晰明了。
所以你完全可以先快速入門,然後有需要再去理解寄存器編程,寄存器編程無非就是按照晶片手冊修改對應的數據、控制、狀態寄存器而已,並不是一個有技術門檻的東西。
STM32官網教程 && 微雪CubeMX教程,不得不說,官方的就是最好的。
文檔也可在公眾號下載:嵌入式思維導圖
四、單片機上的helloworld
到這裡,你就可以按教程配置好自己的工程,寫出STM32的helloworld啦。
除了helloworld外,你還可以實現各種加減乘除,棧、隊列、鍊表、樹等各類數據結構,甚至各類排序查詢算法,這是不是和c語言學習的內容完全一致呢?
當然,你會發現,我在單片機上面跑的程序,怎麼像Visual C++把結果列印出來在電腦看呢?因為單片機還沒驅動螢幕來著?
五、單片機的時鐘、外設
時鐘比較好理解,時鐘是單片機的脈搏,時鐘頻率決定了單片機運行一個指令周期的時。。就好像我們做廣播體操的時候廣播上喊的節拍1234 2234 3234。。。。然後我們全部的同學就按照這個節奏進行一個個動作。節拍越快我們動作越快。節拍越慢我們動作的越慢。
在CubeMX生成的所有工程,都需要配置好時鐘,這樣程序燒錄到單片機才能按設置的主頻跑起來,具體如何設置,就需要學習時鐘配置章節了。
而單片機外設模塊,就和我們需要實現的業務功能息息相關了,常見的外設子模塊如下:GPIO、定時器、串口、SPI、I2C、USB等等。
·你要使用串口列印日誌到電腦,你就學習UART模塊。
·你要定時列印時間,你就學習UART、定時器模塊。
·你要讀取按鍵狀態,你就學習GPIO、外部中斷。
·你要控制LED開關,你就學習GPIO,你要花式點燈,你就學習定時器、PWM、GPIO模塊。
·你要驅動IIC接口溫濕度傳感器,你就學習I2C模塊。
·你要驅動SPI螢幕,你就學習SPI模塊。
·你要驅動電機,你就學習PWM、定時器、計數器模塊。
·你要驅動串口舵機,你就學習UART模塊,根據協議發送16進位數據即可。
六、單片機的業務邏輯
到這裡,你把常用的外設模塊驅動起來了,那怎麼用這些模塊去做出一個產品呢?
例如下面就是一個智能手環的框圖,無非就是GPIO驅動震動器、I2C驅動心率傳感器、SPI驅動螢幕、I2C驅動NFC而已。
至於什麼時候點亮螢幕?多久讀一次的心率傳感器數據?什麼時候震動?用C語言的語法就可以實現啦。比如說定時器定時10s讀取一次心率數據,然後同步更新到螢幕,正常心率顯示綠色圖標,當讀取的數據大於多少時,顯示為紅色。這些都是常見的if switch while基礎的語法可以實現的邏輯。
七、高級的單片機編程
在實現了基本的外設驅動、基本的業務邏輯後,你在想,入門工程師和中高級的單片機開發工程師區別在哪裡?
·懂不懂程序模塊化?
·懂不懂底層與業務解耦?
·懂不懂設計模式?
·懂不懂代碼執行效率優化?
這時候就需要你有各類關鍵詞extern ifndef const volatile、預處理、結構體、指針等稍微深入的C語言使用技巧,學習數據結構、設計模式,看各類開源源碼等等方法,提升自己的綜合能力了。
智能音箱的軟體模塊設計框圖
八、建議
不已解決實際問題為由的學習都是耍流氓。
不已抄代碼開始的學習都是閉門造車。
不要刻意去背晶片手冊、各類寄存器、各類API,學會看手冊、學會搜索、學會提問即可。
思考底層邏輯,技術的出現是因為有場景需要,而不是技術本身,單片機所有的功能點都是為解決某個問題的。
最後,分享初級嵌入開發工程師技術棧供您參考,更多資源獲取可以關注「嵌入式思維導圖」:
說了這麼多,大家記得留意下方評論第一條(或者私信我)有干貨~