2019年8月28日 星期三

Hello World--STM32F205RBT6在MDK5的應用範例

上一篇文章提到

在 CubeMX 可以產生多種編譯環境中常見的程式碼

其中包含 IAR 的 EWARM V7/V8

Keil 的 MDK-ARM V4/V5

還有自家最新推出的 CubeIDE

與第三方(AC6)合作的 SW4STM32

這些編譯環境都可以被 CubeMX 所支援

不過我本身對 MDK 的環境比較熟悉

所以才會以 MDK5 作為範例

如果有機會

建議可以嘗試一下 CubeIDE 或 SW4STM32

官方資源與開源環境是新時代的趨勢

自由度越高的環境才能被更多的使用者接受

等我熟悉過 CubeIDE 及 SW4STM32 後再來跟大家分享

暫時先看看 MDK5 的範例吧 (以官方試用版的空間限制就能完成的專案)

==========================================================

由 CubeMX 所產生的 MDK5 程式碼會包含以下幾個資料夾:

1. Drivers:其中包括 CMSIS (Cortex MCU Software Interface Standard)
及 STM32F2xx_HAL_Driver (STM 官方 HAL 庫)

2. Inc:

程式所需的 include 檔

3. MDK-ARM:

包含專案捷徑及除錯所需的連結檔、燒錄檔

4. Src:

主要程式的原始碼 (使用者修改專用)


然後還有一個 Hello.ioc 的 CubeMX 專用 IO 編輯檔

剛剛產生的檔案中

MDK-ARM資料夾內的資料應該都是空的

因為專案本身還沒經過編譯

所以連結檔與燒錄檔都尚未產生

等第一次編譯過後就會有對應的檔案出現

今天的目標是要完成 Hello World 的任務

所以先進入MDK-ARM的資料夾中

由 Hello.uvprojx 的專案檔開啟專案

這是站長習慣的開啟方式

你也可以先打開 MDK5 由 Project -> Open Project 的方式來開啟

因為是第一次開啟專案

所以 Project 應該還沒把專案列入最近清單中

等編譯完成後就可以由最近清單中去開啟專案

另外

進入專案後第一件要確認的就是燒錄環境的設定

如果您使用的是 ST LINK 當作燒錄的工具

那麼就可以忽略接下來的步驟

不過建議還是檢查一下比較保險

我所使用的是 MDK5 專用的 ULINK2

與專案所建立的 ST LINK 是不一樣的工具

所以要先到 Flash -> Configure Falsh Tools... 中

將 Debug 欄位裡的工具更改為 ULINK2

您可以依照自己所使用的工具進行修改

別忘了要替燒錄工具的韌體進行更新

免得不支援選用的 MCU 就 GG 了

==========================================================

要完成 Hello World 的任務

有幾個重要的觀念要先建立

一般來說

周邊功能有三種方式可以呼叫

第一種是用輪詢

第二種是用中斷

第三種是DMA

這個範例會先以輪詢的方式進行撰寫

先驗證IO動作是正確的

之後再嘗試中斷與DMA的寫法

其次

標準 C 語言有內建通訊的函式 printf ()

要使用這個功能必須引用 <stdio.h> 這個開頭檔

否則編譯過程中會發生語法錯誤

由於通訊功能相關的程式碼放在 usart.c 當中

所以首先要改寫的程式便從 usart.c 開始

==========================================================

/* USER CODE BEGIN 0 */

#include <stdio.h>

/* USER CODE END 0 */

/* USER CODE BEGIN 1 */

#ifdef __GNUC__
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

/* USER CODE END 1 */

在 usart.c 中找到 /* USER CODE BEGIN 0 */ 與 /* USER CODE BEGIN 1 */ 的位置

加入上方的程式碼

因為我們接下來會引用 printf 函式

編譯時會檢查編譯環境的設定

所以定義了編譯環境所必須的參數

而 HAL_UART_Transmit 函式則是 HAL 庫內建功能

在 stm32f2xx_hal_uart.c 中可以找到

功能是將 printf 所要丟出的字串一個一個 Byte 傳送出去

==========================================================

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* USER CODE BEGIN 3 */
printf("\r\n Hello World !! \r\n");
HAL_Delay(1000);
  }
/* USER CODE END 3 */

接下來到主程式 main.c 中

找到 /* USER CODE BEGIN Includes */ 及 /* USER CODE BEGIN 3 */

把上面的程式碼加入

其中 HAL_Dealy 約是每個計數 1mS 的延遲 (在 stm32f2xx_hal.c 中)

設定1000為1秒鐘延遲的意思

然後點擊 Rebuild 鍵先進行第一次編譯動作

之後就等待 MDK5 編譯完成

第一次編譯通常會花上一些時間

完成後執行 Load 將程式燒錄到 MCU 中

如果前面的燒錄工具有設定正確的話

應該很快就可以燒錄(下載)成功

接上 USB<->UART 工具或任何可以觀看 UART 通訊資料的工具

你就可以看到 Hello World !! 字樣

==========================================================

如果你不是很習慣作業系統的寫法

不想使用 printf 來傳送資料

那可以怎麼修改呢?

/* USER CODE BEGIN PV */
uint8_t Enter[] = { 0x0d, 0x0a };
uint8_t Hello[] = { "Hello World !!!" };
/* USER CODE END PV */

/* USER CODE BEGIN 3 */
HAL_UART_Transmit (&huart3, Enter, sizeof(Enter), 0xffff);
HAL_UART_Transmit (&huart3, Hello, sizeof(Hello)-1, 0xffff);
HAL_UART_Transmit (&huart3, Enter, sizeof(Enter), 0xffff);
HAL_Delay(1000);
  }
/* USER CODE END 3 */

回歸到單晶片的概念

就是找到傳送的函式

把要丟出去的字串定義好丟出去就可以了

所以可以不要修改 usart.c 中的內容

只在 main.c 中找到 /* USER CODE BEGIN PV */ 及 /* USER CODE BEGIN 3 */

將上面的程式碼寫入對應的位置上

一樣可以看到 Hello World !!! 的字樣

其中

由於宣告為字串的矩陣會多帶一個空字串

所以使用sizeof()這個功能時要將空字串的計數減掉 [sizeof(Hello)-1]

不然會在通訊中多看到一個 0x00 的碼躲在 Hello World !!!後面

==========================================================

最後要提一下 CubeMX 所要帶給我們的改變與新思維:

第一

不要再以硬體底層的概念來看單晶片程式

因為現在的單晶片都不再是以往簡單幾個周邊功能而已

各個周邊之間的關聯性與複雜度都今非昔比

建立以系統觀的思維來看待程式

嘗試以作業系統的寫法來修正以往的撰寫習慣

可以提高程式的可攜性與移植性

避開重複開發以縮短專案完成的時間

第二

我們不是單晶片大廠的員工

也不是設計單晶片的設計師

不應該為單晶片的驅動與除錯負責

這應該是單晶片大廠所要克服的功課

在高度分工的科技時代

如果還要工程師從頭到尾把晶片廠的問題一一克服才開始開發專案

那開發的進度鐵定落後到天荒地老

並不是我們不具備解決問題的能力

也不是我們缺乏學習的動力與毅力

而是在商言商--時間就是金錢

很多舊時代的大廠還停留在工程師就是要解決所有的開發問題

而忽略分工的責任劃分與時間、專案管理的問題

甚至把問題都怪罪到研發工程師的身上

認為他們程度差且懶惰又不負責任

這是非常落伍且不公平的

第三

工欲善其事,必先利其器

如果有更好的工具可以用

就不要因為習慣了舊工具就排斥接觸新工具

每個學習都有陣痛期

但如果陣痛可以帶來脫胎換骨的大提升

那為何不痛一下就好?

而要一直忍受效率不好的開發工具

讓自己的競爭力越來越不好呢?

人本來就是活到老學到老

不是嗎?

希望你會喜歡這篇文章的介紹

下一篇我們要探討一下中斷與DMA的用法

敬請繼續期待

2019年8月27日 星期二

STM32CubeMX產生專案碼的步驟--STM32F205RBT6在MDK5的應用範例

好久不見,大家最近過得好嗎?

這是理科太太最愛用的開場白

我覺得很實用就搬來借用一下

很長一段時間沒有更新與單晶片有關的訊息

並不是已經脫離了單晶片

而是鑽得更深入後發現了新大陸

在眾說紛紜、無所適從的超大量文件中

找到了最適合自己理解的方法

並打算一系列整理好記錄在這裡

進入主題

今天要介紹的是STM32所推出的STM32CubeMX工具(以下簡稱CubeMX)

目前官方最新版本為5.3.0

如果用過以前4.x的版本

會發現新版本的畫面變得很華麗

畫面分頁的方式讓閱讀更直觀也更簡潔

但習慣了舊畫面的使用者可能需要一點時間適應

因為版面的編排位置有不小的改變

內容上則差不多

==========================================================

開啟CubeMX

第一個看到的是歡迎畫面

正中間的深藍色方框是開啟新專案的選項

左邊則是開啟就專案的選項


右邊則是更新與設定的選項


接下來會先示範一個建立新專案的方法

這是初學者入門時最需要的部分

以往建立新專案的方法

要先到官方下載在編譯環境中適用的MCU韌體封包 (驅動程式碼、固件庫)

然後將整組設定引入編譯環境中

再自己一個一個將需要的功能

從移入的驅動程式碼中找出來設定

只要漏掉一個細節就會導致程式完全不動

而且還找不到病因,欲哭無淚

入門最怕遇到冗長難懂的文字設定流程

特別是因為理解偏差 (語文能力不好) 而產生的誤設定

CubeMX直觀的圖形操作可以省下不少麻煩

往下做你就會發現他的魅力

==========================================================


首先在歡迎畫面的正中間找到 Start My Project from MCU

點選其下方的 ACCESS TO MCU SELECTOR (紅色方框)

進入MCU選單中

在選單中輸入 STM32F205RB 這個 MCU 編號

右下方的畫面會出現與此編號相關的所有MCU選項

如果只輸入 STM32F2 則會出現整個 F2 系列的 MCU

這個選項裡會列出MCU的參考價格、對應的官方開發板、包裝、......

可以初步先確認選用的MCU是不是自己想要的

若點選需要的MCU後 (如STM32F205RB)

右上方則會出現更多與 MCU 相關的訊息


第一個出現的是MCU的基本規格描述 (Features)

和官網上的訊息一致

如果定期更新CubeMX的話

可以隨時看到第一手的MCU資訊



隔壁一欄Block Diagram則是MCU的功能方塊圖

在這個頁面可以快速檢閱 MCU的所有功能



再隔壁一欄Docs & Resources可以看到與該 MCU 相關的所有參考文件

直接點選要看的資料 (如點選RM0033)

就會連結到對應文件的網址直接下載回來


像這樣

連結到對應的文件後就開始下載

下載成功會直接開啟



==========================================================

回到原選單中雙擊 STM32F205RB 這個 MCU 編號

CubeMX會自動進入圖形化MCU設定畫面


出現的畫面是MCU完整腳位的 Pinout

在這裡要先確認一下MCU的包裝有沒有選對

同一個MCU編號可能會有不同的包裝

而不同的包裝可能存在腳位設定上的些許差異

如果發現包裝不對可以在上方的File選單中重新建立New Project

此時可以開始對 MCU的腳位及初始條件做規劃

第一件要做的是點選 System Core進入sys設定燒錄與除錯的方式


設定的方式很簡單也很直觀

就是點選sys

CubeMX就會自動跳出設定視窗


接著在 Debug 中把 Disable 改成 Serisl Wire



這樣就算設定完成了


設定好功能後會在對應的腳位上變成綠色

如果腳位是黃色代表選定的腳位功能還未開啟

要到對應的功能中把需要的設定補上

若是覺得設定視窗很佔畫面

可以把設定視窗收起來

方便檢視MCU腳位並設定

在設定視窗的右上角有兩個三角形的收放功能

點選紅色框框中的三角形就可以收起設定視窗



像這樣

已經設定好的腳位就會以綠色呈現

此時可以繼續對其他功能進行設定

==========================================================

緊接著要開始設定系統的時脈 RCC

由於我的應用是要使用外部石英晶體當成振盪源

所以要在High Speed Clock (HSC) 中選擇 Cyctal / Ceramic Resistor


選擇好之後對應的振盪腳位也會變成綠色



不過接下來要做的並不是繼續在設定視窗中點選功能

而是移到隔壁欄位 Clock Configuration 中去設定系統時脈


在這裡可以直接看到整個MCU所有跟時脈設定有關的方塊圖

要改變的設定直接在欄位中點選輸入就好

輸入的順序是由左而右,由上至下

由於剛剛已經將HSC的外部振盪腳位設定好了

所以在 Clock Configuration 中外部振盪器是以藍色反白呈現

這裡可以輸入實際應用的石英晶體時脈 (如25, 16, 12, 8......)

預設為25MHz





接下來由左到右我依序修改了一些參數來滿足板子的時脈需求

如果單純使用外部振盪器來當系統時脈

那麼設定到頂天也就25MHZ

要跑上120MHz的系統時脈

得靠內部PLLCLK將HSC倍頻上去

所以我將PLLCLK的振盪源指定為HSC

經過除頻(/25) 倍頻(x240) 除頻 (/2) 的設定後

進入系統的振盪時脈變成120MHz

然而周邊匯流排的時脈跟不上系統的時脈 (APB1:30MHz / APB2: 60MHz)

所以分配給匯流排的時脈還要經過(/4) (/2)的除頻過程

點選好就設定完成了

==========================================================

系統時脈設定好

加個周邊功能來試試

一般來說都會加GPIO或"Hello World"的測試 (UART功能)

這裡以UART3的設定作為範例


我所使用的板子

規劃了PC10與PC11當作UART3的功能腳

因此直接在MCU右上方的PC10與PC11點一下

會出現功能選單

選擇USART3_RX與USART3_TX後

MCU的腳位會變成黃色


為什麼是黃色?

前面的文章有提到是功能未啟用

所以到左邊的 Connectivity 選單中找到 USART3 點一下




接著在 Mode 中 把 Disable 改成 Asynchronous




這樣就把UART3的功能打開並對應到PC10與PC11的腳位上

另外一種方法是先在功能選單中把USART3的功能模式設定好

MCU會跳出預設對應的 IO 腳

以本專案為例

選擇USART3之後會出現PB10與PB11兩隻腳

之後再到MCU的PC10與PC11點選USART3_RX / USART3_TX

一樣可以把 IO 正確定義到需要的腳位上

==========================================================

到此為止

我們把MCU要運作的最基本設定都設好了

要開始產生程式碼的專案檔了


將畫面切換到 Project Manager 頁面上

這裡就是要產生程式碼專案前的設定

左邊可以看到三個選單

第一個選單是Project

第二個選單是Code Generator


第三個選單是Advanced Settings




在Project選單中

我們要先給專案一個名字

這裡設為Hello

專案資料夾要擺放的路徑設在桌面上 (可利用Browse鍵改變路徑)

路徑產生後會將專案名稱當作資料夾名稱放在桌面 (指定的路徑) 上

最重要的

就是不要漏掉你所使用的編譯環境設定 (設為 MDK-ARM V5)


切換到下一個 Code Generator 選單中

把紅色方框中的選項勾選

這個功能會把所有MCU的周邊功能獨立成一個成對的.c與.h檔

將來較容易修正程式且方便閱讀

建議要勾選

不然產生的周邊程式碼會全部放在主程式(main.c)中

程式看起來會很累

而 Advanced Settings 選單中會提示你現在周邊功能開啟的狀況

你可以根據需求做一下調整

這裡因為不做調整就直接跳過

做好上面所有的設定後就可以直接將右上角的 GENERATE CODE 鍵點一下


接下來會等待一小段時間

如果您所開啟的功能比較多

產生程式碼的時間也會比較久

專案建立好之後會跳出一個對話視窗

您可以點選開啟資料夾或開啟專案

若您選擇開啟資料夾

就會看到熟悉的MDK5程式碼結構


裡面多了一個以前沒見過的東西 Hello.ioc

這個檔案是CubeMX專用的IO設定檔

你剛剛所有的設定都儲存在這個檔案裡

只要點選Hello.ioc就可以將剛剛的設定呼叫出來

重點是

你可以隨時任意更改這裡的功能設定

並且重新產生新的程式碼

只要在剛剛的Code Generator中有設定Keep User Code when re-generating (預設選項)

所有自己寫好的程式碼都不會被修改

只會更動與功能設定有關的程式碼

==========================================================

CubeMX可以快速配置好一片新板子所需要的所有功能

如果你對板子的功能很熟悉

那麼使用CubeMX便能加速你開發板子的速度

因為CubeMX再好用

也要自己先了解MCU的功能及用法

CubeMX只是充當索引的角色

此外

建立好專案不代表程式已經可以動作了

要say Hello還是得靠自己key程式

下一篇文章要延續這個專案

將MDK5的程式碼結構介紹一下

敬請期待