stm32-TIM之基本定時器
TIM:
STM32F1 系列中,除了互聯型的產品,共有8 個定時器,分為基本定時器,通用定時器和高級定時器。基本定時器TIM6 和TIM7 是一個16 位的只能向上計數的定時器,只能定時,沒有外部IO。通用定時器TIM2/3/4/5 是一個16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,每個定時器有四個外部IO。高級定時器TIM1/8是一個16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,還可以有三相電機互補輸出信號,每個定時器有8個外部IO。
TIM分類:
基本定時器框圖:
1. 時鐘源
定時器時鐘TIMxCLK,即內部時鐘
2. 計數器時鐘
定時器時鐘經過PSC 預分頻器之後,即CK_CNT,用來驅動計數器計數。PSC 是一個16 位的預分頻器,可以對定時器時鐘TIMxCLK 進行1~65536 之間的任何一個數進行分頻。 具體計算方式為:CK_CNT=TIMxCLK/(PSC+1)。
3. 計數器
計數器CNT 是一個16 位的計數器,只能往上計數,最大計數值為65535。當計數達到自動重裝載寄存器的時候產生更新事件,並清零從頭開始計數。
4. 自動重裝載寄存器
自動重裝載寄存器ARR 是一個16 位的寄存器,這裏面裝著計數器能計數的最大數值。當計數到這個值的時候,如果使能了中斷的話,定時器就產生溢出中斷。
5. 定時時間的計算
定時器的定時時間等於計數器的中斷周期乘以中斷的次數。計數器在CK_CNT 的驅動下,計一個數的時間則是CK_CLK 的倒數,等於:1/(TIMxCLK/(PSC+1) ),產生一次中斷的時間則等於:1/ (CK_CLK * ARR)。如果在中斷服務程序裏面設置一個變量time,用來記錄中斷的次數,那麽就可以計算出我們需要的定時時間等於:1/CK_CLK * (ARR+1)*time
bsp_timbase.h文件:
#ifndef __BSP_TIMEBASE_H #define __BSP_TIMEBASE_H #include "stm32f10x.h" #define BASIC_TIM6 // 使用TIM7時,註釋掉該行即可 #ifdef BASIC_TIM6 #define BASIC_TIM TIM6 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM6 //定時周期(從0開始計數) ,得出一次中斷的事件為1000/1M=1ms, #define BASIC_TIM_Period 1000-1 //預分頻,72MHz/(71+1)= 1MHz,(0時,為1分頻) #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM6_IRQn #define BASIC_TIM_IRQHandler TIM6_IRQHandler #else #define BASIC_TIM TIM7 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM7 #define BASIC_TIM_Period 1000-1 #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM7_IRQn #define BASIC_TIM_IRQHandler TIM7_IRQHandler #endif /**************************oˉêyéù?÷********************************/ void BASIC_TIM_Init(void); #endif
bsp_timbase.c文件:
#include "bsp_timbase.h" static void BASIC_TIM_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } static void BASIC_TIM_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE); TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period; TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler; //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM_TimeBaseStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure); //?????????ж???λ TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update); TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE); TIM_Cmd(BASIC_TIM, ENABLE); } void BASIC_TIM_Init(void) { BASIC_TIM_NVIC_Config(); BASIC_TIM_Mode_Config(); }
中斷處理函數:
void SysTick_Handler(void) { } void BASIC_TIM_IRQHandler (void) { if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) { time++; TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update); } }
main.c文件:
#include"stm32f10x.h" #include"bsp_led.h" #include"bsp_timbase.h" volatile uint32_t time = 0; int main(void) { LED_GPIO_Config(); BASIC_TIM_Init(); while(1) { if ( time == 1000 ) //1000 * 1 ms = 1s { time = 0; red_TOGGLE; } } }
stm32-TIM之基本定時器