1. 程式人生 > >stm32填坑之旅一 - stm32f103c8t6點亮板載貼片藍色LED

stm32填坑之旅一 - stm32f103c8t6點亮板載貼片藍色LED

轉載請註明:https://www.cnblogs.com/rockyf/p/11691622.html

開篇

開篇一定要精彩,不然路人不理睬!下述是筆者作為arm小白的填坑之旅
沒錯,這個之前一直從事軟體開發的筆者,開始搞硬體了,當然僅僅是數電!模電需要有很紮實的電路基礎,而筆者有的只有“紮實”的邏輯基礎。
那為什麼筆者要開始搞硬體呢?
其實早在大學期間,筆者所在專業(電腦科學與技術)中就有一門課就專門講了硬體-軟體的連線以及實現,只怪當初沒有好好學,只是心中有那麼個印象,就是時鐘驅動邏輯電路去處理每一個指令然後完成整個邏輯(當然,這個印象很重要,在arm中,時鐘就是它的心臟!)。
畢業後若干年,物聯網行業開始興起,於是手癢癢了,僅憑這一印象,開始入手了人生中的第一塊板子——樹莓派3B,用來做了一些小玩意兒,但那都是在linux的基礎上做的,和軟體開發沒什麼區別,於是乎,這塊樹莓派至今都在吃灰。

第二塊板子便是arduino,比樹莓派稍微有點難度了,沒有OS,且ram也只有幾百KB,做了幾個demo後,發現太依賴arduino的環境了,也不是C開發,並沒有真正接觸底層,於是這塊arduino跟樹莓派正在一起吃灰中。
筆者的主開發語言是js,出於對指令碼語言的熟練,我偶然間發現了NodeMCU這個東西,發現是塊可以用lua指令碼寫邏輯的板子,甚是歡喜,後來還燒錄了espruino韌體和micropython韌體,把玩了許久後終於還是去吃灰了!
看來IoT行業並沒有那麼簡單,於是收收心搞主業了!直到上個月手頭沒啥業務了,又開始手癢癢,查閱了avr和arm的利弊後,最終選擇了arm,畢竟大佬的意見是想挑戰就選arm(其實arduino板就是使用了avr架構的atmega晶片)!於是開始某寶之路。

選材#1 STM32f103c8t6

筆者作為arm初學者,不能上來就搞大貨(比如xx開發套件,xx整合開發板),一是貴,二是沒必要。再三某寶後,最終選定了stm32最便宜的板子STM32f103c8t6,是國產的板子,應該是st授權過的板子,然後各種仿製。
筆者入的是塊黑色板子,如下圖:

這塊板子對於初學者來說太實惠了,RMB11,65536b(64kb)的flash和20480b(20kb)的sram,完全夠用了,還有一個microUSB口,舒服!
當然,某寶上還有其他各種顏色的板子,電路排布略有不同,但功能都不盡相同。

踩坑#1 燒錄

興致勃勃地拿了快遞,興致勃勃地拆了快遞,興致勃勃地拿USB線連線到了電腦,尷尬的是毫無反應,USB資訊裡也沒有任何st字樣的項,於是開始查閱各種資料才發現,stm32f103x的microUSB口是用作電源和DFU燒錄用的,於是又查了DFU的資料,發現stm32f103x並沒有燒錄dfu的支援韌體,所以不能用DFU燒錄,所以還是要其他燒錄方式!

選材#2 st-link v2

在採坑#1後,我查到了stm32的另外兩種燒錄方式:JTag和st-link,JTag在某寶上的價格要幾十塊,而st-link則是10塊上下,但是JTag比st-link要好用,於是果斷選了st-link,便宜和愛折騰才是王道(一點陣圖拉丁人說)。
於是在某寶上又入了一個st-link v2,RMB10.5。

踩坑#2 跑起來了

拿到st-link後,才意識到stm板子上的引腳沒有焊接,於是就把swd引腳和跳線引腳給焊接上了。
然後照著板子上的swd的引腳說明,連線到st-link對應的引腳!

完美,一插上,板子上的貼片藍色LED就開始閃爍起來了(據說藍燈閃爍是出場時候燒錄的測試程式,說明板子是正常工作的)。

踩坑#3 開發環境搭建

在查閱資料的時候,發現大大多數開發者用的作業系統要麼是Windows要麼就是Linux的,而筆者用的macOS,又一個大坑漸漸浮現,我直接填一下吧。
需要材料:

  1. 安裝STM32CubeMX
  2. 安裝homebrew
  3. 安裝stlink命令列工具:brew install stlink
  4. 安裝open-ocd命令列工具:brew install openocd
  5. 安裝Clion2019,筆者比較喜歡jetbrains系列的IDE。記住,一定要安裝新版本,老闆沒有適配和安裝Embedded MCU Development plugin,這個外掛能簡化很多操作!

然後就可以愉快地玩耍了!
開啟clion,新建一個專案,選嵌入式stm32的那個

建立專案後,會自動開啟STM32CubeMX,或者手動開啟專案中的ioc檔案,在編輯區會有一個連結能開啟STM32CubeMX。

它預設建立的是STM32f030f4px的晶片,在下面的操作中修改晶片

然後在project manager中修改

路徑修改了一次就不能修改了哦!最後點選右上角的generate code。
返回clion後,就會同步檔案,發現程式碼都生成了,點選編譯,居然毫不費力地成功了,甚是歡喜!

然後燒錄,點選執行,clion居然報錯了

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


這時,筆者找遍了整個列表都沒找到stm32f103字樣的項,於是去各種查閱,網上說並沒有stm32f1discovery的項,這個low-level的板子太雜了,需要用board/st_nucleo_f103rb.cfg才行。
然後再點選執行,嘿,居然一堆紅色的文子,看得頭皮發麻

然後又是各種查閱,原來要修改board/st_nucleo_f103rb.cfg的配置

  • 把介面改成stlink-v2,原來是stlink-v2-1,筆者買的是stlink-v2,如果你買的是v2-1,那這個不用修改
  • 把最後一行註釋掉 #reset_config srst_only

再執行,嘿,藍燈居然不閃了,估計是燒錄成功了,因為紅色文子裡沒有什麼錯誤資訊了。
然後開始看專案結構,根據筆者的經驗,使用者邏輯的入口肯定是類似src,main之類字樣的檔案中的,果然,在Src/main.c中找到了入口。
裡面有很多註釋,主要是用於STM32CubeMX生成程式碼所標記的,不要亂改這些註釋,否則會對程式碼生成產生影響的,你需要修改的就USER CODE字樣註釋範圍內。
果然找到了藍燈不閃爍的原因了,原來是main方法裡的while裡是空的,導致沒有對藍燈沒有做任何處理,藍燈預設是滅的。
於是開始查閱stm32有關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口的狀態,第一個引數是io口的集合,第二個引數是具體集合中那個口。那為什麼是GPIOB和GPIO_PIN_12呢?

採坑#4 GPIO

STM32f103c8t6板載的藍色LED肯定是能修改的,或者是有其他用途的。經仔細查閱某寶的那個詳情後,找到了它的電路圖

在圖中,找到了兩個LED燈,一個是紅色LED,是接地的,常亮狀態,指示通電狀態。藍色LED則是接入到了PB12,意思就是可以通過PB12的口來控制這個藍燈,於是,推斷一下就是GPIOB和GPIO_PIN_12這兩個引數了(其實是通過多次敲程式碼,在只能提示候選列表中找到的)。
HAL_Delay自然就是延時等待多少毫秒的作用了!
程式碼修改好了,再執行,吧唧,沒反應,藍燈沒有閃也沒有亮,咋回事?預期應該是狂閃的呀!

採坑#5 hal庫和rcc庫

為什麼操作GPIO沒有反應呢?依舊是查閱資料,網上說需要配置GPIO,不然用不了,然後給出了很多程式碼,貼上進來後,都是語法錯誤,什麼RCC沒有找到之類的錯誤,應該是庫沒有引入進來導致的,想include rcc庫,結果在專案中找不到rcc庫,於是又是一番查閱。
筆者這個時候就在想,我用的hal庫,會不會rcc也是類似hal的庫呢,果然不是!hal中也有rcc的部分實現,所以只是用hal庫應該沒什麼問題。
然後就擱置了一段時間!

採坑#6 除錯

我想想看,能不能用除錯功能,因為st-link模擬器是有除錯功能,於是又開始搗騰!
奈何怎麼除錯沒用,GDB偵錯程式始終無法連線st-link:Error: init mode failed (unable to connect to the target)。但是在HAL_Init()上的斷點就能斷到,每次都是HAL_Init()過不去,然後一步一步跟蹤進去除錯,發現在__HAL_AFIO_REMAP_SWJ_NOJTAG這個方法過不去了,再升入就不行了,於是按照__HAL_AFIO_REMAP_SWJ_NOJTAG關鍵詞閱資料發現,stm的除錯是需要在STM32CubeMX中配置的,配置點在:SYS>Debug中

預設是No Debug,選擇Serial Wire後generate code一次再編譯就能開啟除錯了!簡直完美!

採坑#7 引腳配置

但是除錯發現,程式碼很完美啊(其實心裡也沒有底,還是查了其他文件,懷疑板載的藍色LED並不是PB12)。
偶然間想起來,在STM32CubeMX中配置除錯的時候,好像在右側的晶片引腳圖看到了PB這個口子,果然,在晶片引腳圖上找到了PB12,甚是歡喜啊!

然後把PB12的引腳設定成GPIO_OUTPUT,然後generate code,再執行,終於,藍燈開始閃爍啦,舒服!
仔細查閱main.c,會發現,其實在配置引腳後,生成的程式碼的MX_GPIO_Init中多了一些程式碼,這些程式碼就是配置引腳用的!

完結

至此,板載藍色LED終於閃爍了,達成了目標!
其實,在整個填坑過程中,不止上述的那些步驟,還有其他很多坑,比如:

  • stlink命令列工具怎麼都打印不出stm板子的資訊,甚至把stlink的原始碼clone下來,除錯看了log,果然不是stlink的問題!最後在其issue中找到了答案,原來通過swd連線st-link的時候,需要將boot0置1,就是要把boot0的跳線帽連線右側,boot1隨意

    包括燒錄程式,首次連線都需要上圖的連線,否則會報初始化失敗的錯誤!
  • clion無法除錯c的專案,查詢後原來是筆者升級了macOS catalina 10.15版本,導致GDB偵錯程式出錯無法除錯,升級到最新版本即可!
  • 為什麼要把#reset_config srst_only這行註釋掉呢,因為對於STM32f103這樣的的low-level的板子,並不支援reset,所以怎麼都不能重置板子,在燒錄成功,st-link會自動重置板子,所以依舊能達到重置板子的效果!
  • ……想不起來了

心得

寫博怎麼不寫心得呢!
世上本來並沒有坑,只是完成教程太少,便有了坑!
其實在整個填坑過程中,最多的是查閱資料和嘗試,身邊沒有朋友學過或正在從事相關的工作。

  • 查閱資料就是baidu+google,雙劍合璧,baidu查中文,google查英文,幾乎都能找到!
  • STM32f103c8t6這塊板子的flash據說有10w次的擦寫壽命,所以幾乎完全用不完,多嘗試,多失敗,才能達到最終的成功!