首页 > 代码库 > 第八章:STM32定时器

第八章:STM32定时器

时间:2014年8月15日

一、定时器种类:

     1、四个可同步运行的通用定时器(TIM2~TIM5),每个均有一个16位的自动加载递增/递减计数器、一个16位预分频器和4个独立的通道。

      2、两个16位高级控制定时器(TIM1和TIM8)

        特点:由一个可编程预分频器驱动的16为自动装载 计数器组成,与通用定时器有共同处,但功能更强大。

      3、两个基本定时器(TIM6和TIM7)

       特点:主要用于产生DAC触发信号,也可以当作通用的16为时基计数器

      4、实时时钟RTC

       特点:能提供日历/时钟、数据存储等功能。常用作各种计算机系统的时钟信号源和参数设置存储电路。计算准、体积小功耗低。

      5、看门狗(Watchdog)

       特点:用于出错矫正。

      6、SysTick时钟(位于CM3内核)

       特点:24位递减计数器,计数到0,自动重装,同时内部COUNTFLAG标志置位。

二、通用定时器TIMx的功能(略)

2.1、时钟源选择

        计数器时钟可由下列时钟源提供:内部时钟(CK_INT)、外部时钟模式1(输入脚TIx)、外部时钟模式2(外部触发输入ETR)、内部触发(ITRx,一个定时器可作为另外一个定时器的预分频器)

2.2、时基单元

        包括计数器寄存器(TIMx_CNT)、预分频寄存器(TIMx_PSC)和自动装载寄存器(TIMX_ARR)等。

初始化相关数据结构:

typedef struct
{
  u16 TIM_Prescaler;             //预分频因子
  u16 TIM_CounterMode  ;       //定时器模式
  u16 TIM_Period;                   //定时器周期个数
  u16 TIM_ClockDivision;         // 定时器分频因子
  u8 TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;

注:1、TIM_Prescaler:写入预分频器中。a、新的参数要在下一次更新时间来临时被采用。b、计数器由预分频器的时钟输出CK_CNT驱动,需要设置计数器TIMx_CR1中的计数器使能位。

       2、TIM_TimeBaseInitTypeDef:设置干扰的频率限制,对应TIMx_CR1中的第八和第9位的CKD[1:0]

2.3、计数器模式(略)

2.4、定时时间计算

     T=(TIM_Prescaler+1)X(TIM_Period+1)/TIMxCLK

2.5、定时器中断

   TIM2中断通道序号为28,默认优先级35

1)初始化过程:设置寄存器AIRC中PRIGROUP的值,设置优先级的分配——>设置TIM2寄存器,允许相应中断——>设置TIM2的优先级(IP[28])——>设置允许TIM2中断通道。

2)中断响应过程:TIM2的UIE条件成立,TIM2本身中断标志置位,——>申请中断——>Pending标志置位——>执行中断服务程序——>硬件清除Pending标志位

3)执行TIM2的中断服务程序:所有TIM2的中断事件都在一个TIM2中断服务中完成,故需要在中断程序中判断是哪个中断源要服务!

三、实例1

【程序功能】数码管每个1s加一,到F跳转到0(用定时器2中断实现)

1)、主程序初始化

/* TIM2, GPIOA and GPIOB clock enable */RCC初始化配置
  RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB2Periph_GPIOA |
                         RCC_APB2Periph_GPIOB, ENABLE);

/****************NVIC初始化****************************/

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

/* Enable the TIM1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

/*****************GPIO配置************************************

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

   /* GPIOA Configuration: */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure); 
}

/*******************************************************************************
*
*            主函数
*
*******************************************************************************/

int main(void)
{
#ifdef DEBUG
  debug();
#endif

  RCC_Configuration();  //系统时钟配置

  NVIC_Configuration();     //NVIC配置

  GPIO_Configuration();     //通用IO端口配置

  /*-----------------------------------------------------------------------------*/

  /***72M下定时值的计算((1+预分频TIM_Prescaler)/72*(1+定时周期TIM_Period))*/
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //配置RCC,使能TIMx

  /* Time Base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 7199;  //时钟预分频数 例如:时钟频率=72/(时钟预分频+1) 
 
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; ////定时器模式 向上计数 

  TIM_TimeBaseStructure.TIM_Period = 9999;//自动重装载寄存器周期的值(定时时间)累计 0xFFFF个频率后产生个更新或者中断(也是说定时时间到)

  TIM_TimeBaseStructure.TIM_ClockDivision = 0; ////时间分割值 

  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2

  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打开中断 溢出中断 

//打开定时器
  TIM_Cmd(TIM2, ENABLE); 
   /* Main Output Enable */
  TIM_CtrlPWMOutputs(TIM2, ENABLE);

  while (1)
  { 
       GPIO_Write( GPIOB ,  LED7Code[Count%16]<<8); //将Count数据送到GPIOB高八位
    
  }
}