1. 程式人生 > >stm32-TIM之基本定時器

stm32-TIM之基本定時器

clas font 高級 中斷處理函數 eba conf lag 向上 ext

TIM:

  STM32F1 系列中,除了互聯型的產品,共有8 個定時器,分為基本定時器,通用定時器和高級定時器。基本定時器TIM6 TIM7 是一個16 位的只能向上計數的定時器,只能定時,沒有外部IO。通用定時器TIM2/3/4/5 是一個16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,每個定時器有四個外部IO。高級定時器TIM1/8是一個16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,還可以有三相電機互補輸出信號,每個定時器有8個外部IO

TIM分類:

技術分享圖片

基本定時器框圖:

技術分享圖片

1. 時鐘源

定時器時鐘TIMxCLK,即內部時鐘

CK_INT,經APB1 預分頻器後分頻提供,如果APB1預分頻系數等於1,則頻率不變,否則頻率乘以2,庫函數中APB1 預分頻的系數是2,即PCLK1=36M,所以定時器時鐘TIMxCLK=36*2=72M

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之基本定時器