1. 程式人生 > 其它 >09-CubeMx+Keil+Proteus模擬STM32 -定時器(二)

09-CubeMx+Keil+Proteus模擬STM32 -定時器(二)

本文例子參考《STM32微控制器開發例項——基於Proteus虛擬模擬與HAL/LL庫》
原始碼:https://github.com/LanLinnet/STM33F103R6

專案要求

通過定時器中斷的方式,實現流水燈的效果。

硬體設計

  1. 第一節的基礎上,在Proteus中新增電路如下圖所示。

  2. 上一節定時器阻塞延時的基礎上,我們在本專案中同樣使用TIM3進行中斷。時鐘頻率採用預設的8MHz,我們不妨設定PSC為3999,ARR為999,那麼此時可以計算出TIM3的計數脈衝週期為\(T_{CNT}\)為0.5ms,一次中斷的溢位時間\(T_{OUT}\)為0.5s。

  3. 開啟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庫。

  4. 點選“Generator Code”生成Keil工程。

軟體編寫

  1. 本次我們需要實現定時器阻塞延時使得LED燈閃爍,需要用到定時器中斷相關函式,其API文件如下:
    HAL_TIM_Base_Start_IT 定時器開啟中斷



    HAL_TIM_PeriodElapsedCallback 定時器中斷回撥函式

  2. 點選“Open Project”在Keil中開啟工程,雙擊“main.c”檔案。

  3. 與定時器阻塞方式不同,我們只需要在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 */
    

聯合除錯

  1. 點選執行,生成HEX檔案。
  2. 在Proteus中載入相應HEX檔案,點選執行,LED燈呈現流水燈狀態。