09-CubeMx+Keil+Proteus模擬STM32 -定時器(二)
本文例子參考《STM32微控制器開發例項——基於Proteus虛擬模擬與HAL/LL庫》
原始碼:https://github.com/LanLinnet/STM33F103R6
專案要求
通過定時器中斷的方式,實現流水燈的效果。
硬體設計
-
在第一節的基礎上,在Proteus中新增電路如下圖所示。
-
在上一節定時器阻塞延時的基礎上,我們在本專案中同樣使用TIM3進行中斷。時鐘頻率採用預設的8MHz,我們不妨設定PSC為
3999
,ARR為999
,那麼此時可以計算出TIM3的計數脈衝週期為\(T_{CNT}\)為0.5ms,一次中斷的溢位時間\(T_{OUT}\)為0.5s。 -
開啟CubeMX,建立工程。我們首先將PC0-PC7管腳設定為GPIO_Output。
隨後對定時器進行設定:點選“Categories”中的“Timer”列表,選中“TIM3”。在“TIM3 Mode and Configuration”視窗中設定“Clock Source”為Internal Clock
3999
,“Counter Period”為999
。
隨後點選“NVIC Settings”,將定時器3全域性中斷“TIM3 global interrupt”使能。
接下來點選“Clock Configuration”進入時鐘配置介面,這裡我們採用預設設定的8MHz。
最後因為我們的GPIO程式設計採用的是LL庫函式,所以這裡將GPIO設定為LL庫。
-
點選“Generator Code”生成Keil工程。
軟體編寫
-
本次我們需要實現定時器阻塞延時使得LED燈閃爍,需要用到定時器中斷相關函式,其API文件如下:
HAL_TIM_Base_Start_IT 定時器開啟中斷
HAL_TIM_PeriodElapsedCallback 定時器中斷回撥函式
-
點選“Open Project”在Keil中開啟工程,雙擊“main.c”檔案。
-
與定時器阻塞方式不同,我們只需要在main函式中初始化定時器,剩下所有的功能都在中斷回撥函式中執行,這樣的操作模式使得CPU大部分時間工作在main函式的while迴圈中,僅在中斷溢位的時候進入中斷回撥函式中執行指令,大大提高了CPU的利用效率。
我們首先在main.c檔案的main函式中初始化定時器。/* USER CODE BEGIN 2 */ LL_GPIO_WriteOutputPort(GPIOC, 0xfe); HAL_TIM_Base_Start_IT(&htim3); //初始化定時器 /* USER CODE END 2 */
最後,在
/* USER CODE BEGIN 4 */
和/* USER CODE END 4 */
之間插入定時器中斷回撥函式,程式碼如下/* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static uint8_t counter = 0; if(htim == &htim3) //定時器3中斷 { counter++; if(counter>=8) counter=0; LL_GPIO_WriteOutputPort(GPIOC, (0xfe<<counter)|(0xfe>>(8-counter))); //流水燈狀態改變一次 } } /* USER CODE END 4 */
聯合除錯
- 點選執行,生成HEX檔案。
- 在Proteus中載入相應HEX檔案,點選執行,LED燈呈現流水燈狀態。