STM32
直播中

李凤津

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

如何使用STM32定时器的中断来控制LED灯的闪烁呢

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

如何使用STM32定时器的中断来控制LED灯的闪烁呢?

回帖(1)

h1654155275.5835

2021-11-23 10:59:34
  实验工具:MDK5,STM32F103ZET6开发板
  使用固件库编程
  这次学习定时器的中断,还是利用定时器4,CH2通道。因为都是利用定时器,所以和PWM的程序有很多相似之处,因此在PWM的程序中进行修改即可。
  首先需要先了解一下32的定时器;
  STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器。
  STM3 的通用 TIMx (TIM2、 TIM3、 TIM4 和 TIM5)定时器功能包括:
  1)16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。
  2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
  3) 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
  A.输入捕获
  B.输出比较
  C. PWM 生成(边缘或中间对齐模式)
  D.单脉冲模式输出
  4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步威廉希尔官方网站 。
  5)如下事件发生时产生中断/DMA:
  A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
  B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
  C.输入捕获
  D.输出比较
  E.支持针对定位的增量(正交)编码器和霍尔传感器威廉希尔官方网站
  F.触发输入作为外部时钟或者按周期的电流管理
  今天我们用的就是第五种中的更新(溢出)中断,
  首先是中断相关的设置
  Timer.c
  #include “Timer.h”
  #include “led.h”
  #include “sys.h”
  void Tim4_Init(u16 arr,u16 psc)
  {
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; // 初始化结构体
  NVIC_InitTypeDef NVIC_InitStructure; //中断
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能时钟
  //相关配置
  TIM_TimeBaseInitStruct.TIM_Prescaler = psc; //a number between 0x0000 and 0xFFFF
  TIM_TimeBaseInitStruct.TIM_Period = arr; //a number between 0x0000 and 0xFFFF
  TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
  TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //分频因子
  TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);
  //使能指定的TIM中断
  TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  //打开定时器
  TIM_Cmd(TIM4,ENABLE);
  }
  void TIM4_IRQHandler(void) //TIM4中断
  {
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
  {
  TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //清除TIMx的中断标志位:TIM 中断源
  LED1=!LED1;
  }
  }
  新增加的是中断的相关配置,具体可以查看 NVIC_InitTypeDef,
  而 ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)函数则是用来读取中断的类型(比如我们设置的溢出中断),并判断是否发生中断。
  void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
  该函数的作用是,清除定时器 TIMx 的中断 TIM_IT 标志位。
  通过上面简单的几步我们就配置好了定时器的中断,
  然后我们去设置一下LED相关的配置
  #include “led.h”
  void LED_Init(void)
  {
  GPIO_InitTypeDef GPIO_Initstruct;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//定时器时钟使能
  GPIO_Initstruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
  GPIO_Initstruct.GPIO_Pin=GPIO_Pin_13; //设置引脚
  GPIO_Initstruct.GPIO_Speed=GPIO_Speed_50MHz;//设置速度
  GPIO_Init(GPIOD,&GPIO_Initstruct);
  }
  main.c
  
  如果你调试时一直显示
  …USERmain.c(13): warning: #223-D: function “xxxx” declared implicitly
  尽管你已经添加了相关的xxx.h头文件,不妨试试添加 extern声明一下函数 ,说不定会有惊喜。
  只做参考使用,如有不当之处敬请指出。
举报

更多回帖

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