本文例子參考《STM32單片機開發實例——基於Proteus虛擬模擬與HAL/LL庫》 源代碼:https://github.com/LanLinnet/STM33F103R6 項目要求 通過定時器中斷的方式,實現流水燈的效果。 硬體設計 在第一節的基礎上,在Proteus中添加電路如下圖所示。 在 ...
本文例子參考《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
,設置“PSC”為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燈呈現流水燈狀態。