iT邦幫忙

2021 iThome 鐵人賽

DAY 4
1
Arm Platforms

STM32 基礎入門教學系列 第 4

【Day4】:來使用STM32CubeIDE吧!

程式碼導讀

點開我們的main.c檔案,可以看到裡面密密麻麻的註解,第一次看到還真令人害怕,但其實他就真的只是註解而已,但可不能因為他是註解就把這些刪光光喔,它可是有大用處的。
先前提到過CubeIDE可以把我們對於腳位的配置自動生成程式碼,我們只需要在filename.ioc(filename為專案名稱)點一點,儲存後他就會自動生成程式碼了。(後面會更詳細的介紹)。那如果今天你的程式碼已經數百行,IDE怎麼知道要將自動生成的程式碼放在哪呢?實際上程式已經將程式碼做初步的分類,以下是程式碼最上面的幾行。

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

我們可以看到每個類別的開頭都會有長長的虛線,由上到下依序是Includes、Private Includes、Private typedef、Private define,只要該類別是Private開頭的話,後面一定會有USER CODE BEGIN與USER CODE END這兩個註解,我們的程式碼就需要寫在這裡,而生成程式碼時就會安插在這個區間以外的地方。
舉例來說:如果你要定義一個常數你就可以放在Private define內部,如下:

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define PI 3.14159265358
/* USER CODE END PD */

所以很重要很重要很重要的就是你的程式碼一定要放在BEGIN和END之間,否則只要你一生成程式碼,那你的程式碼就會不見了。如果你很不信邪的話可以試試看,我的同學已經幫你試過了,當然結果就是會不見...

不過我們還是有幾點需要觀念澄清

  1. 他畢竟就只是註解,它的功用就只是讓IDE知道他生成程式碼的時候要放在哪裡,因此如果你不放在BEGIN和END之間,你依然可以執行,而且是完全正確的。但是只要一生成程式碼就是會不見。
  2. 雖然他已經幫你分類好了,但你完全可以不照他的分類來寫程式,例如上面定義的圓周率,你也可以放在Includes的BEGIN和END裡面,也可以順利執行。最大的原則就是把程式碼放在BEGIN和END裡面就好。

好用小工具-現場表達式

我們寫程式在debug時候,經常會把你想要監看的變數print/cout出來,但是在STM32CubeIDE在預設情況下是不允許你這麼做的,需要自己做一些設定,與安裝額外軟體。(當時我嘗試了很久仍然沒有成功,索性我就放棄了),那我們要怎麼進行debug呢?
就是用現場表達式(live expression)這個功能了,他就是一個變數監測的小視窗,但他只能對全域變數(沒有被任何大括號框住的變數)進行監測。而由於他是一個debug的工具,因此正常執行的情況下式是不能使用的,需要點選工具列那排小蟲蟲的圖示以debug的方式執行(快捷鍵為F11),執行的時候可能會產生一些視窗提醒,都按Yes即可。接著我們在上面工具列那排的Window->Short View->現場表達式,就會出現在右邊的小視窗了。
https://ithelp.ithome.com.tw/upload/images/20210905/20141525zOnZReabaa.jpg
接下來你會看到你的程式碼停在main函式裡面的第一行,在我這裡的情況下是HAL_Init()這一行
https://ithelp.ithome.com.tw/upload/images/20210905/201415258JalAZAn0o.jpg
非常重要!!!這個時候你的程式碼還沒有開始執行,需要按F8才會開始執行
非常重要!!!這個時候你的程式碼還沒有開始執行,需要按F8才會開始執行
非常重要!!!這個時候你的程式碼還沒有開始執行,需要按F8才會開始執行
真的很重要所以講3次,經常會按F11後發現腳位怎麼沒有正常的輸出,原來是忘了按F8了><
我們來實際使用看看這個功能吧

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  i++;
	  HAL_Delay(1000);

  }
  /* USER CODE END 3 */

要記得在全域的地方新增變數 i
HAL_Delay()
這個函式就像是Arduino的delay(),單位為ms
用debug的方式執行,並在現場表達式的視窗內增加新表達式,就可以看到 i 每隔一秒增加1了
這個現場表達式還有個厲害的功能,可以直接打上&var(var為你要監測的變數),這樣可以直接獲取這個變數的記憶體位置,接下來會來應用這個功能。

好用工具-Memory

這個工具的目的是取代Arduino的序列阜的功能,由於STM32並沒有提供人和單晶片溝通的介面,我們在測試的過程中經常會需要調整參數,因此就需要頻繁的上傳程式,而用這個功能就可以直接更改變數的值。
變數是存放在RAM當中,因此我們這個動作就是直接更改RAM的數值

一樣是在debug的模式下才可以使用,預設會在底下的視窗,若沒有出現一樣可以從Window->Short View->Memory裡面找到。
首先點綠色的+新增一個你要監測的記憶體位置
https://ithelp.ithome.com.tw/upload/images/20210905/20141525D8UhFjLo5E.jpg
https://ithelp.ithome.com.tw/upload/images/20210905/20141525JtQBMbOfCo.jpg
接著右邊就會跑出許多框框,預設會是用Hex(十六進位)來表達記憶體的值。右邊New Renderings的地方新增你要解讀這個記憶體的方式,如果你要監測的變數是有號的整數,就選Signed Integer。
我們來實際使用看看這個功能吧
在全域的地方宣告一個變數x,並用現場表達式的方式獲取他的記憶體位置,以我來說,x這個變數放在0x20000028這個位置(不過實際上是0x20000028~0x2000002B,因為int是四個bytes嘛)
https://ithelp.ithome.com.tw/upload/images/20210905/20141525pUryotdXvu.jpg
接著就按照上面的步驟新增要監看的記憶體位置
https://ithelp.ithome.com.tw/upload/images/20210905/201415255ewtNzojOT.jpg
選擇Signed Integer作為解讀的方式
https://ithelp.ithome.com.tw/upload/images/20210905/20141525v3JPeXDqbe.jpg
就可以順利看到0x20000028~0x2000002B的值啦,並且會以int的方式解讀
https://ithelp.ithome.com.tw/upload/images/20210905/20141525icjvjp44kE.jpg
我們可以直接更改這個位置的值,直接點你要更改的記憶體位置,輸入新的值就OK了,順便使用現場表達式來確認這個值是法順利地被更動了。我順利的將x更改為31415926~
https://ithelp.ithome.com.tw/upload/images/20210905/20141525Y9zeDN7OmH.jpg

小結

今天順利地執行了程式碼,並且介紹兩個好用的小工具,明天開始我們就要真正的開始來使用STM32單晶片了


上一篇
【Day3】:STM32CubeIDE安裝以及環境設定
下一篇
【Day5】:GPIO輸入輸出(上)
系列文
STM32 基礎入門教學30

尚未有邦友留言

立即登入留言