CubeIDE Note 03: Lesson 1. Basic I/O Setting And Application for LL Library
教學
如何使用 CubeIDE 設定 GPIO (General Purpose Input/Output, GPIO)腳位及基本應用
環境
本文使用
OS: Windows x64
STM32CubeIDE Version: 1.6.1
開發板: NUCLEO-F334R8(STM32F334R8)
Low-Layer (LL) Library
教學文章列表
參考資料
UM2570. Description of STM32G4 HAL and low-layer drivers
RM0364. STM32F334xx advanced Arm®-based 32-bit MCUs
UM1735. Discovery kit for STM32F3 series with STM32F334C8 MCU
General Purpose Input/Output (GPIO) — 成大資工wiki
STM32 BSRR寄存器和BRR寄存器 — CSDN
STM32 GPIO 配置之ODR, BSRR, BRR 详解-CSDN
Section 1. 基本題
使用以下三種方式來GPIO達成I/O腳位之高/低電位輸出。
Methods:
(i) LL Library Function
LL_GPIO_SetOutputPin(GPIO_TypeDef * GPIOx, uint32_t PinMask)
LL_GPIO_ResetOutputPin(GPIO_TypeDef * GPIOx, uint32_t PinMask)(ii) LL Library Funciton
LL_GPIO_TogglePin(GPIO_TypeDef * GPIOx, uint32_t PinMask)(iii) 直接寫入暫存器
GPIOx->BSRR
GPIOx->BRR
撰寫程式碼,量測GPIO PA4之訊號使其呈現以下數據。
(a) 使用(i)達成 Freq = 1kHz, Period =1ms
(b) 使用(ii)達成 Freq = 2kHz, Period = 500us
(c) 使用(iii)達成 Freq = 8kHz, Period = 125us
Section 1.1 CubeMX 設定
Step 1. 請先按照此篇教學(選對開發板)做好基礎設定
Step 2. 把需要的IO Pin腳設定好
在 Pinout & Configuration 分頁,切換到 Pinout View在MCU圖上找到 PA4
左鍵點選打開選單,將其設定為 GPIO_Output
Step 3. 可切到 GPIO 項目,確認 Pin 腳設定細項
筆者在 Step 2. 也順便將進階題所要使用的腳位設定好了
Step 4. 切換到Project Manager修改函數庫設定
預設皆為 HAL庫
GPIO改為 LL
RCC維持 HAL不變
參考資料:關於 ST 各種函數庫之介紹(推薦閱讀)
Step 5. 按下上方黃色齒輪,即可產生程式框架
範例 ioc檔案備份 (適用 STM32F334R8):
https://drive.google.com/file/d/1BON_hNiUkZyQMjJUERwU7oUvq-ENjnOZ/view?usp=sharing
Appendix. GPIO設定程式碼解析
打開 main.c程式,找到 MX_GPIO_Init()原代碼
Section 1.2 暫存器介紹
A. GPIO port input data register (GPIOx_IDR)
GPIO輸入狀態暫存器,可讀
B. GPIO port output data register (GPIOx_ODR)
GPIO輸出狀態暫存器,可讀可寫
官方建議不要寫入,由 BSRR或 BRR來做會更好
C. GPIO port bit set/reset register (GPIOx_BSRR)
GPIO 輸出 set /reset暫存器,可寫
寫 1才動作,寫 0 無動作(保持原樣)
Set (BS)優先權高於 Reset (BR)
D. GPIO port bit reset register (GPIOx_BRR) (x = A to D and F)
GPIO輸出 Reset暫存器,可寫
寫 1才動作,寫 0 無動作(保持原樣)
Section 1.3 程式碼撰寫
Step 1. 結構介紹
主程式通常都是寫在main.c的 int main(void)區塊中
初次撰寫有以下三點要注意:
A. 自己撰寫的程式碼,只有放在
/* USER CODE BEGIN x*/ 與 /* USER CODE END x*/
之間區塊,才不會在Generate Code時被覆寫掉
寫之前最好先確認清楚 Begin與 End之位置
B. /* USER CODE BEGIN x*/ 與 /* USER CODE END x*/ 標記無法自行新增
C. 只有放在while(1)區塊中的程式碼會無限執行
Step 2. 範例程式
LL_GPIO_WriteOutputPort 是對一個 GPIOx 全部 Pin 一起寫入 0 / 1
(a) 使用(i)達成 Freq = 1kHz, Period =1ms
(b) 使用(ii)達成 Freq = 2kHz, Period = 500us
(c) 使用(iii)達成 Freq = 8kHz, Period = 125us
PA4其實是第 5個 pin(從 PA0開始)
其實 LL函數庫的函數,就是把直接操作暫存器的步驟經過一層函數包裝
Step 3. 到此就可以把程式燒進去了
有用過 CodeComposer的同學,應該就可以發現接下來操作與其非常類似
A. 接上開發板,按下綠色蟲蟲
B. 然後就會看到這個錯誤提示視窗
C. 這是因為還沒設定 Debug 模式,按下Debug Configurations來設定
D. 只要選好 CubeIDE 預設好的 Debug 設定,按下 Debug 即可
STM32 Cortex-M C/ C++ Application 展開 選 “專案名 Debug”
E. 新板子的ST-Link 韌體可能是舊版,所以需要更新
按 OK
按下 Open in update mode
按下 Upgrade
等待跑完,視窗消失即可
F. 重新按下綠色蟲蟲,就可以看到熟悉的 Debug 介面
可以按上方的綠色執行鍵,讓程式開始 Run 了
如果遇到這個錯誤,只要拔掉板子重新接上即可
Step 4. 使用HAL_Delay()做delay
如果我們直接把上述程式燒進去開發板測試,
會發現週期完全不對,多1000倍出來,
這是因為HAL庫之HAL_Delay()函數,
在72M主頻且CubeMX自動產生的設定下,
HAL_Delay(1)為延時1ms,
我們要修正設定,將HAL_Delay(1)修改為1us
在 main.c 裡面的 int main()區塊裡找到這位置加上以下程式即可
Section 1.4 實驗結果
實際上測量出來的結果都跟我們預想的差了一點,
主因是Delay的精度問題
(a) 使用(i)達成 Freq = 1kHz, Period =1ms
(b) 使用(ii)達成 Freq = 2kHz, Period = 500us
(c) 使用(iii)達成 Freq = 8kHz, Period = 125us
Section 2. 進階題
將 PA4~PA7 等4腳位接LED燈,使用 PB10 作 Input,使用以下提示方法,完成本題目
可用Methods:
(i) LL Library Function
LL_GPIO_ReadInputPort(GPIO_TypeDef * GPIOx)(ii) LL Library Funciton
LL_GPIO_IsInputPinSet(GPIO_TypeDef * GPIOx, uint32_t PinMask)(iii) 直接讀取暫存器
GPIOx->IDR
當 PB10 接收低電位(0V)時,
4顆LED燈左右來回閃爍(跑馬燈),完成來回一次閃爍之時間為1秒;
當 PB10 接收高電位(3.3V)時,
4顆LED燈交替閃爍,每交替之時間間隔為0.5秒。
Section 2.1 程式碼撰寫
筆者提供比較簡短的寫法,不熟悉的同學也可以使用暴力解
如果是做完第一題接著做第二題的同學,記得註解掉以下代碼
不然會看到所有LED燈一起發光喔
Section 2.2 實驗結果
在影片中可看到將PB10拉高或拉低電位,可讓LED出現不同動作
附錄
參考手冊官方下載連結
Datasheet. STM32F334x4 STM32F334x6 STM32F334x8
RM0364. STM32F334xx advanced Arm®-based 32-bit MCUs
UM1735. Discovery kit for STM32F3 series with STM32F334C8 MCU
UM2609. STM32CubeIDE user guide
https://www.st.com/resource/en/user_manual/dm00629856-stm32cubeide-user-guide-stmicroelectronics.pdf