CubeIDE Note 04: Lesson 2. Timer Setting And Application for LL Library

Hsueh-Ju Wu 吳學儒
STM32CubeIDE
Published in
12 min readJun 5, 2021

教學

如何使用 CubeIDE 設定 Timer 及中斷基本應用

環境

本文使用
OS: Windows x64
STM32CubeIDE Version: 1.6.1
開發板: NUCLEO-F334R8(STM32F334R8)
Low-Layer (LL) Library

教學文章列表

參考資料

UM2570. Description of STM32G4 HAL and low-layer drivers

https://www.st.com/resource/en/user_manual/dm00610707-description-of-stm32g4-hal-and-lowlayer-drivers--stmicroelectronics.pdf

RM0364. STM32F334xx advanced Arm®-based 32-bit MCUs

https://www.st.com/resource/en/reference_manual/dm00093941-stm32f334xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

UM1735. Discovery kit for STM32F3 series with STM32F334C8 MCU

https://www.st.com/resource/en/user_manual/dm00108524--discovery-kit-for-stm32f3-series-with-stm32f334c8-mcu-stmicroelectronics.pdf

(STM32) NVIC (Nested vectored interrupt controller) 學習

https://www.cnblogs.com/ollie-lin/p/10934604.html

Section 1. 基本題

使用Timer 1計時器,產生週期為50us之中斷,並在每次進入中斷時將PA4作轉態(Toggle)的動作。

Section 1.1 CubeMX 設定

Step 1. 請先按照此篇教學(選對開發板)做好基礎設定

Step 2. 把需要的IO Pin腳設定好

可參閱上一篇GPIO教學

Step 4. 設定Timer1

打開Timers列表,選擇Timer 1進行設定

在 Mode裡找到 Clock Source,
Clock Source 設定為 Internal Clock

此時再切換到 Clock Configuration 分頁
可看到TIM1的時脈設定已被啟用
預設是使用 APB2 (PCLK2) 之時脈 72 MHz

可切換為PLLCLK*2 獲得最高時脈 144MHz

從手冊可以查到更詳細的時脈走線圖,可發現一樣結果

Clock Tree (RM0364. p. 107)

得知Timer1 Internal Source Clock (內部時鐘時脈) 為 72MHz
我們就可以來設定需要的 Timer1 Prescaler了
切回到 Timer1 設定頁面,Configuration 修改為下方設定

Counter Settings
Prescaler:71(72–1)
Counter Period: 49(50 – 1)
auto-reload preload: Enable

auto-reload preload控制是否自動加載重載 Counter

以下針對 Prescaler 與 Counter Period 設定做講解:

因為 Timer1 Source Clock 為72MHz,
理論上將Prescaler設為72,即可得到1MHz (1us)之時脈
但這裡得注意到STM32F334這塊開發板的暫存器設定
由手冊裡面可查到,頻率會等於Timer1 Source Clock / (PSC+1)
所以要除72倍頻,得設為71,它會自動加1上去

RM0364. p.464

而Counter Period設為49,即可得到50*1us = 50us 之週期
這是設定Counter要數到的"值"而不是"次數",
Counter會從0開始數,所以數的次數是設定值+1
要數50次,值只要設為49即可

RM0364. p. 388

Step 5. 設定Timer1中斷

在CubeMX裡設定中斷很簡單,只需要打個勾就好

切換到 NVIC 設定
TIM1 update and TIM16 interrupts打勾

NVIC (Nested vectored interrupt controller) 參考資料:
https://www.cnblogs.com/ollie-lin/p/10934604.html

Step 6. 更改使用函數庫

把 TIM 改為 LL庫

Step 7. 按下Generate Code產生程式框架

範例 ioc檔案備份 (適用 STM32F334R8):
https://drive.google.com/file/d/1H2N73fkJ80lOqxTeAinoJog23LADqJNi/view?usp=sharing

Appendix 1. GPIO設定程式碼解析

打開 main.c程式,找到 MX_TIM1_Init()原代碼

Appendix 2. 產生設定報告核對設定項目

範例程式設定報告檔案
https://drive.google.com/file/d/1WC_rjyDk3QMTJQnW6W664DHUsVt8S1-G/view?usp=sharing

Generate Report 是個可產生設定檔概要的功能(pdf檔)
當ioc檔案看到眼花撩亂時
可以匯出這個檔案幫助檢查設定有無錯誤

報告會產生在專案根目錄下

打開檔案後,我們跳到TIM1即可看到相關設定

*米字的設定值就是我們自己修改過的部分
也可以順便檢查到有無更動到不需要更動的設定

MCU資料,其他Clock、Pin 設定也在這份報告中看的到

Section 1.2 暫存器介紹

中斷暫存器

未完待補

Section 1.3 程式碼撰寫

Step 1. 主程式部分

main.c 部分 /* USER CODE BEGIN 2 */ 加入以下代碼

Step 2. 中斷程式部分

CubeIDE 架構中的中斷函數
全部放在 stm32f3xx_it.c 裡面
打開 stm32f3xx_it.c 在 TIM1_UP_TIM16_IRQHandler(void)
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */ 加入以下代碼

中斷使用有三點要記得:
A. Timer Counter 要啟用,否則不會計數
B. 使用中斷函數要啟用(Enable)對應之中斷事件
C. 中斷函數中要清除(Clear)對應事件的旗標
可以在手冊中找到相關的函數描述與名稱

啟用中斷的關鍵字是 EnableIT,_後面帶事件名稱

此次用到的 Update事件就是指計數器觸發後的重載更新事件

LL_TIM_EnableIT_UPDATE (UM2570. p. 2659)

清除中斷旗標的關鍵字是 ClearFlag,_後面帶事件名稱

LL_TIM_ClearFlag_UPDATE (UM2570. p. 2647)

Section 1.4 實驗結果

可看到產生週期為100us之方波(每50us轉態一次),結果正確

Section 2. 進階題

使用以下兩設定
Timer1計時器,產生週期為100us中斷;
Timer2計時器,產生週期為100us中斷。

完成以下題目
(a) 設定中斷優先權Timer1大於Timer2,使用PA4與PA5之Toggle驗證功能。(b) 設定中斷優先權Timer2大於Timer1,使用PA4與PA5之Toggle驗證功能。

Timer1 觸發 PA4轉態; Timer2 觸發 PA5轉態

(c) 利用Timer1計時器,產生週期為40ms,且Duty為75%之訊號並輸出於PA4。

Section 2.1 CubeMX 設定

Timer週期設定參考基本題即可
設定完成,記得按下Generate Code重新產生新設定程式代碼

中斷優先權

參考資料:
https://zhuanlan.zhihu.com/p/61333581

本小節會著重在解講如何設定中斷優先權部分
中斷優先權也是在NVIC設定項裡控制
設定有以下規則存在:

A.
優先權主要由 Preemption Priority 控制(紅框設定)
數字越小,優先權越高,預設為 0
若同時觸發時,優先權高的優先執行

B.
若不同時觸發,Preemption Priority 數值低的"可"中斷數值高的事件

譬如有一個 Preemption Priority = 1的事件 A正在執行,
此時有一個 Preemption Priority = 0的事件 B發生中斷,
則事件 A會被中斷,優先執行事件 B

C.
Preemption Priority 且 Sub Priority (紫框設定)數值皆相同,先到的先執行
不會執行途中被中斷

D.
若Preemption Priority相同,Sub Priority 不同時
若同時觸發,則Sub Priority優先權高的先執行
若不同時觸發,Sub Priority 數值小的"不可"中斷數值高的事件

Sub Priority 數字越小,優先權越高,預設為 0

NVIC 之 Preemption Priority (紅框設定) 與 Sub Priority (紫框設定)

- ioc檔
https://drive.google.com/file/d/1tYK6EalufUeEB6Xw03_OSu9p_asAouRV/view?usp=sharing

- 設定報告( pdf )
https://drive.google.com/file/d/1Rwj_YXQ8LlQSpmnEXHFUV6zZzKzs5LoY/view?usp=sharing

Section 2.2 程式碼撰寫

(a) 設定中斷優先權Timer1大於Timer2,使用PA4與PA5之Toggle驗證功能。(b) 設定中斷優先權Timer2大於Timer1,使用PA4與PA5之Toggle驗證功能。

main.c

stm32f3xx_it.c

(c) 利用Timer1計時器,產生週期為40ms,且Duty為75%之訊號並輸出於PA4。

stm32f3xx_it.c

全域變數寫法是寫在上方的BEGIN與END標籤中,
沒寫在標記區塊裡,重新Generate Code後會不見喔

Section 2.3 實驗結果

CH1黃色:PA4(Timer1觸發轉態)
CH2藍色:PA5(Timer2觸發轉態)

(a) 設定中斷優先權Timer1大於Timer2,使用PA4與PA5之Toggle驗證功能

可由波形看到PA4比PA5還早轉態為高電位
可得知Timer1優先權高於Timer2

(b) 設定中斷優先權Timer2大於Timer1,使用PA4與PA5之Toggle驗證功能

可由波形看到PA5比PA4還早轉態為高電位
可得知Timer2優先權高於Timer1

(c) 利用Timer1計時器,產生週期為40ms,且Duty為75%之訊號並輸出於PA4

筆者家的示波器不知道出了甚麼trouble,Duty顯示25%
用眼睛看都知道是75%吧XDD,已確認沒開啟波形反相

--

--