STM32
直播中

李丹

8年用户 1471经验值
私信 关注
[问答]

怎样去配置STM32F103通用定时器的定时中断

STM32F103通用tiMx定时器功能包括哪些?

怎样去配置STM32F103通用定时器的定时中断?

回帖(1)

张桂兰

2021-11-23 11:45:20
  1. 通用TIMx简介
  通用定时器(TIM2、TIM3、TIM4和TIM5)是一个通过可编程预分频器驱动的16位自动装载计数器构成。
  
  1.1 TIMx主要功能
  通用TIMx定时器功能包括:
  ● 16位向上、向下、向上/向下自动装载计数器
  ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
  ● 4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出
  ● 使用外部信号控制定时器和定时器互连的同步电路
  ● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获 ─ 输出比较
  ● 支持针对定位的增量(正交)编码器和霍尔传感器电路
  ● 触发输入作为外部时钟或者按周期的电流管理
  1.2 时基单元
  ● 计数器寄存器 (TIMx_CNT)
  ● 预分频器寄存器 (TIMx_PSC)
  ● 自动装载寄存器 (TIMx_ARR)
  计数器由预分频器的时钟输出CK_CNT驱动,仅当设置了计数器TIMx_CR1寄存器中的计数器使能位(CEN)时,CK_CNT才有效。
  预分频器可以将计数器的时钟频率按1到65536之间的任意值分频,它是基于一个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器,将定时器时钟CK_PSC分频为CK_CNT。
  自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器,当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于’0’时,产生更新事件。
  
  2定时器中断的用法
  配置定时中断
  Tout:定时器溢出时间,Tclk:定时器时钟频率
  
  通用定时器TIMx挂载在总线APB1下,总线APB1时钟总线AHB时钟分频的得到,一般情况AHB会设置为最高72MHZ,APB1时钟则由AHB时钟2分频,为最高36MHZ,由于APB1预分频系数不为1,通用定时器TIMx时钟为APB1时钟的2倍,72MHZ。
  假如,配置500ms的定时器中断;设置好TIMx_PSC和TIMx_ARR的值,不要超过 65535就行。
  配置定时中断的步骤
  1、能定时器时钟
  RCC_APB1PeriphClockCmd();
  2、初始化定时器,配置ARR,PSC
  TIM_TimeBaseInit();
  3、开启定时器中断,配置NVIC
  void TIM_ITConfig();
  NVIC_Init();
  4、使能定时器
  TIM_Cmd();
  5、编写中断服务函数
  TIMx_IRQHandler();
  例程
  #include “timer.h”
  //通用定时器3中断初始化
  //这里时钟选择为APB1的2倍,而APB1为36M
  //arr:自动重装值。
  //psc:时钟预分频数
  //这里使用的是定时器3!
  void TIM3_Int_Init(u16 arr,u16 psc)
  {
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  //定时器TIM3初始化
  TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  //中断优先级NVIC设置
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
  TIM_Cmd(TIM3, ENABLE); //使能TIMx
  }
  //定时器3中断服务程序
  void TIM3_IRQHandler(void) //TIM3中断
  {
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
  {
  TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
  LED1=!LED1;
  }
  }
  3 配置PWM输出
  捕获/比较模式寄存器1(TIMx_CCMR1) 位6:4 OC1M[2:0]
  110:PWM模式1- 在向上计数时,一旦TIMx_CNT《TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT》TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
  111:PWM模式2- 在向上计数时,一旦TIMx_CNT《TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT》TIMx_CCR1时通道1为有效电平,否则为无效电平。
  综上,PWM模式1,向上计数时,TIMx_CNT《TIMx_CCR1输出高电平,否则为低电平 即TIMx_CCR1越大输出PWM占空比越大。 占空比为
  
  向下计数时, 占空比同上
  PWM模式2,向上计数时,TIMx_CNT《TIMx_CCR1输出低电平,否则为高电平 即TIMx_CCR1越大输出PWM占空比越小。 占空比为
  
  向下计数时, 占空比同上
  配置PWM的基本步骤,采用原子开发板,呼吸灯LED1需要将TIM3通道2部分重映射到PB5
  1、使能定时器3和相关IO口时钟。
  使能定时器3时钟:RCC_APB1PeriphClockCmd();
  使能GPIOB时钟:RCC_APB2PeriphClockCmd();
  2、初始化IO口为复用功能输出。函数:GPIO_Init();
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  3、这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,
  所以需要开启AFIO时钟。同时设置重映射。
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
  4、初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
  5、初始化输出比较参数:TIM_OC2Init();
  6、使能预装载寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
  6、使能定时器。TIM_Cmd();
  7、不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();
  例程
  //TIM3 PWM部分初始化
  //PWM输出初始化
  //arr:自动重装值
  //psc:时钟预分频数
  void TIM3_PWM_Init(u16 arr,u16 psc)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
  GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2-》PB5
  //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
  //初始化TIM3
  TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  //初始化TIM3 Channel2 PWM模式
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
  TIM_Cmd(TIM3, ENABLE); //使能TIM3
  }
  3.1 改变占空比
  然后调用下列代码来改变CRR的值
  TIM_SetComparex();
  3.2 改变输出频率
  4 输入捕获
举报

更多回帖

发帖
×
20
完善资料,
赚取积分