stm32学习笔记——定时器(1)


目的:操作通用定时器实现基本时基

配置文件:#include "stm32f10x_gpio.h"

          #include "stm32f10x_rcc.h" 

          #include "stm32f10x_tim.h"//定时器头文件

          #include "misc.h"//定时器中断头文件

寄存器:参阅stm32参考手册

 

结构体定义:

 

typedef struct

{

  uint16_t TIM_Prescaler;   //预分频系数,对时钟源进行任意系数分频

      

  uint16_t TIM_CounterMode;       //计数模式

 

  uint16_t TIM_Period;            //计数周期

 

  uint16_t TIM_ClockDivision;     //外部时钟分频系数(这个例子里FIRE没有使用)

 

  uint8_t TIM_RepetitionCounter; 

} TIM_TimeBaseInitTypeDef; 

 

其中参数有宏定义为

计数模式宏定义:

#define TIM_CounterMode_Up                 ((uint16_t)0x0000)

#define TIM_CounterMode_Down               ((uint16_t)0x0010)

#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)

#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)

#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)

外部分频系数宏定义:

#define TIM_CKD_DIV1                       ((uint16_t)0x0000)

#define TIM_CKD_DIV2                       ((uint16_t)0x0100)

#define TIM_CKD_DIV4                       ((uint16_t)0x0200)

其中定时器时间的计算公式:

时间 = 1 / (预分频系数 +1/ 时钟频率)*周期,由此公式可以看出32定时器功能强大在于其预分频可以任意调节定时器时钟的频率,灵活性大大加强。

 

库函数:

 

 

 TIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct)

定时器时基初始化函数,用于将TIM_TimeBaseInitTypeDef;结构体内各项参数写入指定的寄存器,参数:定时器号,&TIM_TimeBaseInitTypeDef;结构体定义变量名称)。

 

TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)清除定时器的标志位,参数:定时器号,定时器标志位。其中定时器标志位有多个,均有对应的宏定义如下:

#define TIM_FLAG_Update                    ((uint16_t)0x0001) 更新标志位,定时器重新计数

#define TIM_FLAG_CC1                       ((uint16_t)0x0002)捕获标志位

#define TIM_FLAG_CC2                       ((uint16_t)0x0004)

#define TIM_FLAG_CC3                       ((uint16_t)0x0008)

#define TIM_FLAG_CC4                       ((uint16_t)0x0010)

#define TIM_FLAG_COM                       ((uint16_t)0x0020)

#define TIM_FLAG_Trigger                   ((uint16_t)0x0040)

#define TIM_FLAG_Break                     ((uint16_t)0x0080)

#define TIM_FLAG_CC1OF                     ((uint16_t)0x0200)

#define TIM_FLAG_CC2OF                     ((uint16_t)0x0400)

#define TIM_FLAG_CC3OF                     ((uint16_t)0x0800)

#define TIM_FLAG_CC4OF                     ((uint16_t)0x1000)

 

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)查看中断状态,参数为定时器号,中断标志位,返回值为中断状态的值(SET  or  RESTET)。其中中断标志位有宏定义如下:

#define TIM_IT_Update                      ((uint16_t)0x0001)

#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)

#define TIM_IT_Break                       ((uint16_t)0x0080)

 

TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)清除定时器中断标志位

 

TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)定时器中断配置函数,参数:定时器号,中断标志位,使能或不使能。

 

TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)定时器使能函数,参数:定时器号,使能或不使能。

 

程序代码分析:(代码出自FIRE

主函数中:

LED_GPIO_Config();      /* LED初始化*/

   TIM2_Configuration();   /* 定时器初始化*/

TIM2_NVIC_Configuration();  /* 中断向量初始化 */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);//开启定时器2时钟, 配置为72MHz

  while(1) //进入大循环等待定时器中断发生

  {

    if ( time == 1000 ) /* 定时到1s */

    {

      time = 0;    //计数值清零

      /* LED1立刻取反 */      

LED1_TOGGLE; 

    }        

  }

 

配置文件中:

 

void TIM2_NVIC_Configuration(void) //中断向量配置,由于只用到了一个,所以可以随便搞

{

    NVIC_InitTypeDef NVIC_InitStructure; 

    

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;   

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}

 

void TIM2_Configuration(void)  //定时器2配置

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);

    //TIM_DeInit(TIM2);开启定时器2时钟,72MHz

    TIM_TimeBaseStructure.TIM_Period=1000; //周期设为1000

    TIM_TimeBaseStructure.TIM_Prescaler= 71;//预分频为71

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//外部时钟分频,没用到

    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //调用初始化函数

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清一下标志位

    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能定时器中断

    TIM_Cmd(TIM2, ENABLE); //使能定时器

    

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , DISABLE);  //先关闭时钟,main函数里再打开

 

中断函数里:

{

if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )  //读取中断状态

{

time++;                                          //计数器加1

TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);   //清一下标志位 

}  

}

你可能感兴趣的:(stm32学习笔记——定时器(1))