基于STM32定時器中斷講解(HAL庫)
1、定時器簡單介紹
以STM32F103C8T6中幾個定時器為例:
- TIM1:這是一個高級定時器,不僅具備基本的定時中斷功能,還擁有內外時鐘源選擇、輸入捕獲、輸出比較、編碼器接口以及主從觸發模式等多種功能。這使得TIM1能夠適用于各種復雜的應用場景,為開發者提供強大的時間控制和信號處理能力。
- TIM2、TIM3和TIM4:這些是通用定時器,同樣具有定時功能,但在功能上與高級定時器有所區別。通用定時器通常用于實現一些基本的定時任務,如LED閃爍、脈沖寬度測量等。
每個定時器都由一個**16位計數器、預分頻器和自動重裝寄存器的時基單元組成。**預分頻器可以對時鐘進行分頻,計數器則對預分頻后的時鐘進行計數。當計數器的值達到設定值時,會觸發中斷,從而執行相應的定時任務。
以下是總結框圖
2、定時器工作原理
定時器核心是計數器。
講解:首先時鐘源經過預分頻器(一般為72MHZ/36MHZ),內部一般取72,然后進行計數,當計數器時間超過預設時間,則會產生中端。ARR是為了將CNT進行自動清空,重新計數。
3、定時器框圖
參考stm32f103c8t6中文參考手冊:
為防止看不同,特地將此圖進行簡化,以下是簡化圖:
結合手冊進行觀看。【注意:PSC寫0則為1分頻】
4、定時器計數模式
計數模式主要分為向上計數、向下計數、中心對齊計數。
下圖為三種計數方式的圖解:
當溢出時則會觸發中斷。一般采用向上計數。
5、定時器溢出時間計算
舉例:如用內部時鐘源72MHZ則(PSC+1)/F=T=1/f,表示計一個數所用的時間。ARR為重裝載,根據所需要的時間Tout來配置重裝載(ARR+1)表示要計的數目。
比如要計500ms,則ARR可以為4999,PSC為7199。
6、定時器中斷的配置
#include "timer.h"
#include "led.h"
TIM_HandleTypeDef timer_handle = {0};//定義結構體//時基工作參數配置
void timer_init(uint16_t ARR,uint16_t PSC)//傳入ARR自動重裝寄存器和PSC分頻(16位寄存器)
{timer_handle.Instance = TIM2;//用哪個時鐘timer_handle.Init.Prescaler = PSC;//PSC分頻timer_handle.Init.Period = ARR;//傳入ARR自動重裝寄存器的值timer_handle.Init.CounterMode = TIM_COUNTERMODE_UP;//計數模式向上計數timer_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//自動重載寄存器(可用可不用)HAL_TIM_Base_Init(&timer_handle);HAL_TIM_Base_Start_IT(&timer_handle);
}//map函數
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)//弱函數經常被其他函數直接自動調用
{if(htim->Instance == TIM2){__HAL_RCC_TIM2_CLK_ENABLE();HAL_NVIC_SetPriority(TIM2_IRQn,2,2);HAL_NVIC_EnableIRQ(TIM2_IRQn);}}//中斷服務函數編寫
void TIM2_IRQHandler(void)
{HAL_TIM_IRQHandler(&timer_handle);//公共中斷函數
}//回調函數配置
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//弱函數經常被其他函數直接自動調用
{
if(htim->Instance == TIM2)
{led_toggle();//寫入功能,根據自己需要進行完善
}
}
//弱函數拿指針定義,其余拿變量
附圖:
定時器中斷配置圖。