STM32通用定時(shí)器中斷

STM32F1 的通用定時(shí)器是一個(gè)通過可編程預(yù)分頻器(PSC,16位,1~65535)驅(qū)動的 16 位自動裝載計(jì)數(shù)器(CNT)構(gòu)成。STM32 的通用定時(shí)器可以被用于:測量輸入信號的脈沖長度(輸入捕獲)或者產(chǎn)生輸出波形(輸出比較和 PWM)等。 使用定時(shí)器預(yù)分頻器和 RCC 時(shí)鐘控制器預(yù)分頻器,脈沖長度和波形周期可以在幾個(gè)微秒到幾個(gè)毫秒間調(diào)整。定時(shí)器相關(guān)的庫函數(shù)主要集中在固件庫文件 stm32f10x_tim.h 和 stm32f10x_tim.c 文件中。

(1)使能定時(shí)器時(shí)鐘(以定時(shí)器3為例)
void TIM3_Int_Init(u16 arr,u16 psc)   //初始化函數(shù)保留重加載值arr和與分頻系數(shù)psc兩個(gè)入口參數(shù)
{

}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時(shí)鐘使能

其中APB1和APB2中的定義如下:

/** @defgroup APB1_peripheral 
  * @{
  */

#define RCC_APB1Periph_TIM2              ((uint32_t)0x00000001)
#define RCC_APB1Periph_TIM3              ((uint32_t)0x00000002)
#define RCC_APB1Periph_TIM4              ((uint32_t)0x00000004)
#define RCC_APB1Periph_TIM5              ((uint32_t)0x00000008)
#define RCC_APB1Periph_TIM6              ((uint32_t)0x00000010)
#define RCC_APB1Periph_TIM7              ((uint32_t)0x00000020)
#define RCC_APB1Periph_TIM12             ((uint32_t)0x00000040)
#define RCC_APB1Periph_TIM13             ((uint32_t)0x00000080)
#define RCC_APB1Periph_TIM14             ((uint32_t)0x00000100)
#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)
#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)
#define RCC_APB1Periph_SPI3              ((uint32_t)0x00008000)
#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)
#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)
#define RCC_APB1Periph_UART5             ((uint32_t)0x00100000)
#define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)
#define RCC_APB1Periph_I2C2              ((uint32_t)0x00400000)
#define RCC_APB1Periph_USB               ((uint32_t)0x00800000)
#define RCC_APB1Periph_CAN1              ((uint32_t)0x02000000)
#define RCC_APB1Periph_CAN2              ((uint32_t)0x04000000)
#define RCC_APB1Periph_BKP               ((uint32_t)0x08000000)
#define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)
#define RCC_APB1Periph_DAC               ((uint32_t)0x20000000)
#define RCC_APB1Periph_CEC               ((uint32_t)0x40000000)
 
#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x81013600) == 0x00) && ((PERIPH) != 0x00))

/**
  * @}
  */
/** @defgroup APB2_peripheral 
  * @{
  */

#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)
#define RCC_APB2Periph_GPIOF             ((uint32_t)0x00000080)
#define RCC_APB2Periph_GPIOG             ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)
#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000400)
#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000800)
#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)
#define RCC_APB2Periph_TIM8              ((uint32_t)0x00002000)
#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)
#define RCC_APB2Periph_ADC3              ((uint32_t)0x00008000)
#define RCC_APB2Periph_TIM15             ((uint32_t)0x00010000)
#define RCC_APB2Periph_TIM16             ((uint32_t)0x00020000)
#define RCC_APB2Periph_TIM17             ((uint32_t)0x00040000)
#define RCC_APB2Periph_TIM9              ((uint32_t)0x00080000)
#define RCC_APB2Periph_TIM10             ((uint32_t)0x00100000)
#define RCC_APB2Periph_TIM11             ((uint32_t)0x00200000)

#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))
/**
  * @}
  */ 

(2)初始化定時(shí)器,配置ARR,PSC
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動的自動重裝載寄存器周期的值   
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim,參數(shù)有TIM_CKD_DIV1,TIM_CKD_DIV2,TIM_CKD_DIV4
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計(jì)數(shù)模式,向下計(jì)數(shù)為TIM_CounterMode_Down

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位

關(guān)于中斷時(shí)間的計(jì)算:

Tout(溢出時(shí)間)=(ARR+1)(PSC+1) / fclk

其中,ARR為重裝載值,PSC為預(yù)分配系數(shù),fclk為系統(tǒng)時(shí)鐘頻率。 fclk / (PSC+1)其實(shí)得到的是分頻后的頻率,倒數(shù)后變成周期。
系統(tǒng)初始化的時(shí)候在默認(rèn)的系統(tǒng)初始化函數(shù) SystemInit 函數(shù)里面已經(jīng)初始化 APB1 的時(shí)鐘為 2 分頻,所以 APB1 的時(shí)鐘為 36M,而從 STM32 的內(nèi)部時(shí)鐘樹圖得知:當(dāng) APB1 的時(shí)鐘分頻數(shù)為 1 的時(shí)候,TIM2~7 的時(shí)鐘為 APB1 的時(shí)鐘,而如果 APB1 的時(shí)鐘分頻數(shù)不為 1,那么 TIM2~7 的時(shí)鐘頻率將為 APB1 時(shí)鐘的兩倍。

TIM_CounterMode 的作用:
http://blog.sina.com.cn/s/blog_76c545390100ovfj.html

(3)開啟定時(shí)器中斷,配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //在主函數(shù)main()中設(shè)置分組,設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
NVIC_InitTypeDef NVIC_InitStructure;

//中斷優(yōu)先級NVIC設(shè)置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優(yōu)先級0級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優(yōu)先級3級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能指定的TIM3中斷,允許更新中斷

中斷配置函數(shù) TIM_ITConfig的說明:

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
//其中第二個(gè)參數(shù)很重要,定義如下
#define TIM_IT_Update                      ((uint16_t)0x0001)//最常用,更新中斷,計(jì)數(shù)器向上溢出/向下溢出,計(jì)數(shù)器初始化(通過軟件或者內(nèi)部/外部觸發(fā)) 
#define TIM_IT_CC1                         ((uint16_t)0x0002)
#define TIM_IT_CC2                         ((uint16_t)0x0004)
#define TIM_IT_CC3                         ((uint16_t)0x0008)
#define TIM_IT_CC4                         ((uint16_t)0x0010)//都是捕獲/比較中斷,貌似都是平等的,即輸入捕獲,輸出比較
#define TIM_IT_COM                         ((uint16_t)0x0020)
#define TIM_IT_Trigger                     ((uint16_t)0x0040)//觸發(fā)事件(計(jì)數(shù)器啟動、停止、初始化或者由內(nèi)部/外部觸發(fā)計(jì)數(shù))
#define TIM_IT_Break                       ((uint16_t)0x0080)
(4)使能定時(shí)器
TIM_Cmd(TIM3, ENABLE);  //使能TIM3    

至此,初始化完成。

(5)編寫中斷服務(wù)函數(shù)
void TIM3_IRQHandler(void)   //TIM3中斷
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發(fā)生與否
        {
        //各種中斷服務(wù)函數(shù)內(nèi)容
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIM3更新中斷標(biāo)志 
        }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容