STM32
直播中

张玉珍

7年用户 1008经验值
私信 关注
[问答]

怎样去配置STM32F1系列通用定时器的结构体呢

STM32F1系列共有多少个定时器呢?

STM32F1系列通用定时器的特点有哪些?
怎样去配置STM32F1系列通用定时器的结构体呢?

回帖(1)

陈莉

2021-11-23 15:28:58
  一,定时器
  STM32F1系列共有 八个定时器
  2高级,4通用,2基本
  
  二,通用定时器
  
  (一)通用定时器的特点:
  ①在APB1低速总线上
  ②16位向上/向下计数模式,有自动重装载计数器 (TIMx_CNT)
  ③16位可编程,有预分频器(计数器时钟频率的分频系数为1~65535,任意数值) (TIMx_PSC)
  ④有四个独立通道,互不影响 (TIMx_CH1~4)
  1.输入捕获 2.输出比较 3.PWM生成 4.单脉冲模式输出
  ⑤可使用外部信号 (TIM_ETR)
  1.计数器模式
  向上,向下,向上/向下双计数模式
  
  计数到我们设定的数值时,就产生一个溢出事件
  (二)通用定时器工作过程
  
  时基单元:
  ①预分频器:在使用APB1倍频器时,进入这个分频器使用除法,就可以使用1~65535分频系数
  ②计数器:
  ③自动重装载寄存器:
  
  周期计数寄存器属于高级定时器的
  
  三,通用定时器结构体的配置
  1,计数器时钟的计算方法
  
  APB1时钟如果分频系数不是为“1”的话,就可能是36M(兆),
  那么需要 2,362=72,将其改为72M
  【(CK_PSC)预分频器+1】÷N=(CK_CNT)计数器
  2,结构体的配置
  typedef struct
  {
  uint16_t TIM_Prescaler; //初始化预分频值
  uint16_t TIM_Period; //设定自动装载值
  uint16_t TIM_CounterMode; //设定计数模式
  uint16_t TIM_ClockDivision; //输入捕获使用
  } TIM_TimeBaseInitTypeDef;
  3,固件库函数的使用
  void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//定时器初始化
  void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//定时器使能
  FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); //定时器状态标志位
  void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); //定时器清楚标志位
  ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); //定时器中断标志位
  void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);//定时器清楚中断标志位
  4,配置的基本步骤
  ①使能时钟ABP1,定时器TIM2
  ②配置定时器结构体
  ③开启中断NVIC,配置中断的结构体
  ④中断服务函数
  定时器配置每秒进行一次的方法
  Tout = [ 重装载值(ARR+1) * 分频系数(PSC+1)] /Tclk
  Tout = [ 自动重装载值10000(ARR9999+1) * 分频系数。即预分频值7200(PSC7199+1)] /Tclk72M(72 000 000)
  (若要0.5秒,则是重装载值 5000(4999+1))
  5,通用定时器的相关寄存器
  1.计数器寄存器CNT : 当前计数值
  2.预分频寄存器 : 分频系数 (PSC+1) / N = CNT
  3.自动重装载寄存器: 重装载值
  4.控制寄存器: 控制计数方向
  #include “stm32f10x.h”
  #include “tim.h”
  void tim_demo(void)
  {
  TIM_TimeBaseInitTypeDef TimInitStruct;
  NVIC_InitTypeDef NvicInitStruct;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//TIM2定时器在APB1时钟上,进行使能,RCC外设
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置中断优先级组
  TimInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //输入捕获使用,“DIV1”就是分频为1,即不分频
  TimInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //计数模式,选择了向上
  TimInitStruct.TIM_Period=10000-1; //设定自动装载值 。因为要设置每1秒发生一次,选择的这2个数值
  TimInitStruct.TIM_Prescaler=7200-1; //初始化预分频值
  TIM_TimeBaseInit(TIM2, &TimInitStruct); //结构体初始化
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//开启定时器的中断,标志位选择“TIM_IT_Update”,允许更新中断源
  TIM_Cmd(TIM2, ENABLE);//使能结构体
  NvicInitStruct.NVIC_IRQChannel=TIM2_IRQn;//TIM2定时器中断源
  NvicInitStruct.NVIC_IRQChannelCmd=1;
  NvicInitStruct.NVIC_IRQChannelPreemptionPriority=1;
  NvicInitStruct.NVIC_IRQChannelSubPriority=ENABLE;
  NVIC_Init(&NvicInitStruct);
  }
  #include “stm32f10x.h”
  #include “led.h”
  #include “tim.h”
  #include 《stdio.h》
  int main()
  {
  LED_demo();
  tim_demo();
  GPIO_SetBits(GPIOC, GPIO_Pin_13); //灭灯
  while(1)
  {
  }
  }
  //TIM2_IRQHandler 中断服务函数
  void TIM2_IRQHandler(void)
  {
  static uint16_t temp;//定义一个局部静态变量,就会每次默认初始化为0
  if(TIM_GetITStatus(TIM2, TIM_IT_Update)!=RESET)//中断标志位 “TIM_IT_Update”
  {
  if(temp++%2 ==1) //temp进来中断一次就++,%2判断奇数偶数
  {
  GPIO_ResetBits(GPIOC, GPIO_Pin_13);
  }
  else
  {
  GPIO_SetBits(GPIOC, GPIO_Pin_13);
  }
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除中断标志位,
  }
  }
举报

更多回帖

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