轉(zhuǎn)載請(qǐng)注明:http://www.itdecent.cn/p/c6fdd7254d3f

開篇
沒有時(shí)間只是自己找的借口罷了!
開篇一定要精彩,不然路人不理睬!下述是筆者作為arm小白的填坑之旅
沒錯(cuò),這個(gè)之前一直從事軟件開發(fā)的筆者,開始搞硬件了,當(dāng)然僅僅是數(shù)電!模電需要有很扎實(shí)的電路基礎(chǔ),而筆者有的只有“扎實(shí)”的邏輯基礎(chǔ)。
那為什么筆者要開始搞硬件呢?
其實(shí)早在大學(xué)期間,筆者所在專業(yè)(計(jì)算機(jī)科學(xué)與技術(shù))中就有一門課就專門講了硬件-軟件的連接以及實(shí)現(xiàn),只怪當(dāng)初沒有好好學(xué),只是心中有那么個(gè)印象,就是時(shí)鐘驅(qū)動(dòng)邏輯電路去處理每一個(gè)指令然后完成整個(gè)邏輯(當(dāng)然,這個(gè)印象很重要,在arm中,時(shí)鐘就是它的心臟?。?br>
畢業(yè)后若干年,物聯(lián)網(wǎng)行業(yè)開始興起,于是手癢癢了,僅憑這一印象,開始入手了人生中的第一塊板子——樹莓派3B,用來做了一些小玩意兒,但那都是在linux的基礎(chǔ)上做的,和軟件開發(fā)沒什么區(qū)別,于是乎,這塊樹莓派至今都在吃灰。
第二塊板子便是arduino,比樹莓派稍微有點(diǎn)難度了,沒有OS,且ram也只有幾百KB,做了幾個(gè)demo后,發(fā)現(xiàn)太依賴arduino的環(huán)境了,也不是C開發(fā),并沒有真正接觸底層,于是這塊arduino跟樹莓派正在一起吃灰中。
筆者的主開發(fā)語言是js,出于對(duì)腳本語言的熟練,我偶然間發(fā)現(xiàn)了NodeMCU這個(gè)東西,發(fā)現(xiàn)是塊可以用lua腳本寫邏輯的板子,甚是歡喜,后來還燒錄了espruino固件和micropython固件,把玩了許久后終于還是去吃灰了!
看來IoT行業(yè)并沒有那么簡(jiǎn)單,于是收收心搞主業(yè)了!直到上個(gè)月手頭沒啥業(yè)務(wù)了,又開始手癢癢,查閱了avr和arm的利弊后,最終選擇了arm,畢竟大佬的意見是想挑戰(zhàn)就選arm(其實(shí)arduino板就是使用了avr架構(gòu)的atmega芯片)!于是開始某寶之路。
選材#1 STM32f103c8t6
筆者作為arm初學(xué)者,不能上來就搞大貨(比如xx開發(fā)套件,xx集成開發(fā)板),一是貴,二是沒必要。再三某寶后,最終選定了stm32最便宜的板子STM32f103c8t6,是國(guó)產(chǎn)的板子,應(yīng)該是st授權(quán)過的板子,然后各種仿制。
筆者入的是塊黑色板子,如下圖:

這塊板子對(duì)于初學(xué)者來說太實(shí)惠了,RMB11,65536b(64kb)的flash和20480b(20kb)的sram,完全夠用了,還有一個(gè)microUSB口,舒服!
當(dāng)然,某寶上還有其他各種顏色的板子,電路排布略有不同,但功能都不盡相同。
踩坑#1 燒錄
興致勃勃地拿了快遞,興致勃勃地拆了快遞,興致勃勃地拿USB線連接到了電腦,尷尬的是毫無反應(yīng),USB信息里也沒有任何st字樣的項(xiàng),于是開始查閱各種資料才發(fā)現(xiàn),stm32f103x的microUSB口是用作電源和DFU燒錄用的,于是又查了DFU的資料,發(fā)現(xiàn)stm32f103x并沒有燒錄dfu的支持固件,所以不能用DFU燒錄,所以還是要其他燒錄方式!
選材#2 st-link v2
在采坑#1后,我查到了stm32的另外兩種燒錄方式:JTag和st-link,JTag在某寶上的價(jià)格要幾十塊,而st-link則是10塊上下,但是JTag比st-link要好用,于是果斷選了st-link,便宜和愛折騰才是王道(一位圖拉丁人說)。
于是在某寶上又入了一個(gè)st-link v2,RMB10.5。
踩坑#2 跑起來了
拿到st-link后,才意識(shí)到stm板子上的引腳沒有焊接,于是就把swd引腳和跳線引腳給焊接上了。
然后照著板子上的swd的引腳說明,連接到st-link對(duì)應(yīng)的引腳!

完美,一插上,板子上的貼片藍(lán)色LED就開始閃爍起來了(據(jù)說藍(lán)燈閃爍是出場(chǎng)時(shí)候燒錄的測(cè)試程序,說明板子是正常工作的)。
踩坑#3 開發(fā)環(huán)境搭建
在查閱資料的時(shí)候,發(fā)現(xiàn)大大多數(shù)開發(fā)者用的操作系統(tǒng)要么是Windows要么就是Linux的,而筆者用的macOS,又一個(gè)大坑漸漸浮現(xiàn),我直接填一下吧。
需要材料:
- 安裝STM32CubeMX
- 安裝homebrew
- 安裝stlink命令行工具:brew install stlink
- 安裝open-ocd命令行工具:brew install openocd
- 安裝arm-none-eabi-gcc命令行工具:brew tap ArmMbed/homebrew-formulae && brew install arm-none-eabi-gcc
- 安裝Clion2019,筆者比較喜歡jetbrains系列的IDE。記住,一定要安裝新版本,老版本沒有適配和安裝Embedded MCU Development plugin,這個(gè)插件能簡(jiǎn)化很多操作!
然后就可以愉快地玩耍了!
打開clion,新建一個(gè)項(xiàng)目,選嵌入式stm32的那個(gè)

創(chuàng)建項(xiàng)目后,會(huì)自動(dòng)打開STM32CubeMX,或者手動(dòng)打開項(xiàng)目中的ioc文件,在編輯區(qū)會(huì)有一個(gè)鏈接能打開STM32CubeMX。

它默認(rèn)創(chuàng)建的是STM32f030f4px的芯片,在下面的操作中修改芯片

然后在project manager中修改

路徑修改了一次就不能修改了哦!最后點(diǎn)擊右上角的generate code。
返回clion后,就會(huì)同步文件,發(fā)現(xiàn)代碼都生成了,點(diǎn)擊編譯,居然毫不費(fèi)力地成功了,甚是歡喜!

然后燒錄,點(diǎn)擊運(yùn)行,clion居然報(bào)錯(cuò)了

原來是編輯器板子的配置文件沒有選定,需要再run/debug configuration中配置


這時(shí),筆者找遍了整個(gè)列表都沒找到stm32f103字樣的項(xiàng),于是去各種查閱,網(wǎng)上說并沒有stm32f1discovery的項(xiàng),這個(gè)low-level的板子太雜了,需要用board/st_nucleo_f103rb.cfg才行。
然后再點(diǎn)擊運(yùn)行,嘿,居然一堆紅色的文子,看得頭皮發(fā)麻

然后又是各種查閱,原來要修改board/st_nucleo_f103rb.cfg的配置
- 把接口改成stlink-v2,原來是stlink-v2-1,筆者買的是stlink-v2,如果你買的是v2-1,那這個(gè)不用修改
- 把最后一行注釋掉 #reset_config srst_only
再運(yùn)行,嘿,藍(lán)燈居然不閃了,估計(jì)是燒錄成功了,因?yàn)榧t色文子里沒有什么錯(cuò)誤信息了。
然后開始看項(xiàng)目結(jié)構(gòu),根據(jù)筆者的經(jīng)驗(yàn),用戶邏輯的入口肯定是類似src,main之類字樣的文件中的,果然,在Src/main.c中找到了入口。
里面有很多注釋,主要是用于STM32CubeMX生成代碼所標(biāo)記的,不要亂改這些注釋,否則會(huì)對(duì)代碼生成產(chǎn)生影響的,你需要修改的就USER CODE字樣注釋范圍內(nèi)。
果然找到了藍(lán)燈不閃爍的原因了,原來是main方法里的while里是空的,導(dǎo)致沒有對(duì)藍(lán)燈沒有做任何處理,藍(lán)燈默認(rèn)是滅的。
于是開始查閱stm32有關(guān)GPIO的文檔,可以使用hal庫來操作
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);
HAL_Delay(100);
}
HAL_GPIO_TogglePin方法是切換io口的狀態(tài),第一個(gè)參數(shù)是io口的集合,第二個(gè)參數(shù)是具體集合中那個(gè)口。那為什么是GPIOB和GPIO_PIN_12呢?
采坑#4 GPIO
STM32f103c8t6板載的藍(lán)色LED肯定是能修改的,或者是有其他用途的。經(jīng)仔細(xì)查閱某寶的那個(gè)詳情后,找到了它的電路圖

在圖中,找到了兩個(gè)LED燈,一個(gè)是紅色LED,是接地的,常亮狀態(tài),指示通電狀態(tài)。藍(lán)色LED則是接入到了PB12,意思就是可以通過PB12的口來控制這個(gè)藍(lán)燈,于是,推斷一下就是GPIOB和GPIO_PIN_12這兩個(gè)參數(shù)了(其實(shí)是通過多次敲代碼,在只能提示候選列表中找到的)。
HAL_Delay自然就是延時(shí)等待多少毫秒的作用了!
代碼修改好了,再運(yùn)行,吧唧,沒反應(yīng),藍(lán)燈沒有閃也沒有亮,咋回事?預(yù)期應(yīng)該是狂閃的呀!
采坑#5 hal庫和rcc庫
為什么操作GPIO沒有反應(yīng)呢?依舊是查閱資料,網(wǎng)上說需要配置GPIO,不然用不了,然后給出了很多代碼,粘貼進(jìn)來后,都是語法錯(cuò)誤,什么RCC沒有找到之類的錯(cuò)誤,應(yīng)該是庫沒有引入進(jìn)來導(dǎo)致的,想include rcc庫,結(jié)果在項(xiàng)目中找不到rcc庫,于是又是一番查閱。
筆者這個(gè)時(shí)候就在想,我用的hal庫,會(huì)不會(huì)rcc也是類似hal的庫呢,果然不是!hal中也有rcc的部分實(shí)現(xiàn),所以只是用hal庫應(yīng)該沒什么問題。
然后就擱置了一段時(shí)間!
采坑#6 調(diào)試
我想想看,能不能用調(diào)試功能,因?yàn)閟t-link仿真器是有調(diào)試功能,于是又開始搗騰!
奈何怎么調(diào)試沒用,GDB調(diào)試器始終無法連接st-link:Error: init mode failed (unable to connect to the target)。但是在HAL_Init()上的斷點(diǎn)就能斷到,每次都是HAL_Init()過不去,然后一步一步跟蹤進(jìn)去調(diào)試,發(fā)現(xiàn)在__HAL_AFIO_REMAP_SWJ_NOJTAG這個(gè)方法過不去了,再升入就不行了,于是按照__HAL_AFIO_REMAP_SWJ_NOJTAG關(guān)鍵詞閱資料發(fā)現(xiàn),stm的調(diào)試是需要在STM32CubeMX中配置的,配置點(diǎn)在:SYS>Debug中

默認(rèn)是No Debug,選擇Serial Wire后generate code一次再編譯就能開啟調(diào)試了!簡(jiǎn)直完美!
采坑#7 引腳配置
但是調(diào)試發(fā)現(xiàn),代碼很完美啊(其實(shí)心里也沒有底,還是查了其他文檔,懷疑板載的藍(lán)色LED并不是PB12)。
偶然間想起來,在STM32CubeMX中配置調(diào)試的時(shí)候,好像在右側(cè)的芯片引腳圖看到了PB這個(gè)口子,果然,在芯片引腳圖上找到了PB12,甚是歡喜?。?br>

然后把PB12的引腳設(shè)置成GPIO_OUTPUT,然后generate code,再運(yùn)行,終于,藍(lán)燈開始閃爍啦,舒服!
仔細(xì)查閱main.c,會(huì)發(fā)現(xiàn),其實(shí)在配置引腳后,生成的代碼的MX_GPIO_Init中多了一些代碼,這些代碼就是配置引腳用的!
完結(jié)
至此,板載藍(lán)色LED終于閃爍了,達(dá)成了目標(biāo)!
其實(shí),在整個(gè)填坑過程中,不止上述的那些步驟,還有其他很多坑,比如:
-
stlink命令行工具怎么都打印不出stm板子的信息,甚至把stlink的源碼clone下來,調(diào)試看了log,果然不是stlink的問題!最后在其issue中找到了答案,原來通過swd連接st-link的時(shí)候,需要將boot0置1,就是要把boot0的跳線帽連接右側(cè),boot1隨意
image.png
包括燒錄程序,首次連接都需要上圖的連接,否則會(huì)報(bào)初始化失敗的錯(cuò)誤!
- clion無法調(diào)試c的項(xiàng)目,查找后原來是筆者升級(jí)了macOS catalina 10.15版本,導(dǎo)致GDB調(diào)試器出錯(cuò)無法調(diào)試,升級(jí)到最新版本即可!
- 為什么要把#reset_config srst_only這行注釋掉呢,因?yàn)閷?duì)于STM32f103這樣的的low-level的板子,并不支持reset,所以怎么都不能重置板子,在燒錄成功,st-link會(huì)自動(dòng)重置板子,所以依舊能達(dá)到重置板子的效果!
- ……想不起來了
心得
寫博怎么能不寫心得呢!
世上本來并沒有坑,只是完成教程太少,便有了坑!
其實(shí)在整個(gè)填坑過程中,最多的是查閱資料和嘗試,身邊沒有朋友學(xué)過或正在從事相關(guān)的工作。
- 查閱資料就是baidu+google,雙劍合璧,baidu查中文,google查英文,幾乎都能找到!
- STM32f103c8t6這塊板子的flash據(jù)說有10w次的擦寫壽命,所以幾乎完全用不完,多嘗試,多失敗,才能達(dá)到最終的成功!
