[STM32F4] STM32F4---通用定时器更新中断

[复制链接]
1448|33
 楼主| lxs0026 发表于 2022-11-18 15:01 | 显示全部楼层
使能 TIM3 的更新中断,格式为:

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
 楼主| lxs0026 发表于 2022-11-18 15:03 | 显示全部楼层
TIM3 中断优先级设置。

在定时器中断使能之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器,设置中断优先级
 楼主| lxs0026 发表于 2022-11-18 15:04 | 显示全部楼层
使能 TIM3

配置完后要开启定时器,通过 TIM3_CR1 的 CEN 位来设置。在固件库里面使能定时器的函数是通过 TIM_Cmd 函数来实现的:

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
 楼主| lxs0026 发表于 2022-11-18 15:05 | 显示全部楼层
使能定时器 3,方法为:

TIM_Cmd(TIM3, ENABLE); //使能 TIMx 外设
 楼主| lxs0026 发表于 2022-11-18 15:05 | 显示全部楼层
编写中断服务函数

在最后,还是要编写定时器中断服务函数,通过该函数来处理定时器产生的相关中断。

在中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作

使用更新(溢出)中断,在状态寄存器 SR 的最低位。在处理完中断之后应该向 TIM3_SR 的最低位写 0,来清除该中断标志。
 楼主| lxs0026 发表于 2022-11-18 15:09 | 显示全部楼层
在固件库函数里面,用来读取中断状态寄存器的值判断中断类型的函数是:

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
 楼主| lxs0026 发表于 2022-11-18 15:16 | 显示全部楼层
该函数的作用是,判断定时器 TIMx 的中断类型 TIM_IT 是否发生中断。比如,我们要判断定
时器 3 是否发生更新(溢出)中断,方法为:

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
 楼主| lxs0026 发表于 2022-11-18 15:17 | 显示全部楼层
固件库中清除中断标志位的函数是:

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
 楼主| lxs0026 发表于 2022-11-18 15:18 | 显示全部楼层
该函数的作用是,清除定时器 TIMx 的中断 TIM_IT 标志位。在TIM3 的溢出中断发生后,我们要清除中断标志位,方法是:

TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
 楼主| lxs0026 发表于 2022-11-18 15:20 | 显示全部楼层
固件库还提供了两个函数用来判断定时器状态以及清除定时器状态标志位的函数 TIM_GetFlagStatus 和 TIM_ClearFlag,他们的作用和前面两个函数的作用类似。只是在 TIM_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而TIM_GetFlagStatus 直接用来判断状态标志位。
 楼主| lxs0026 发表于 2022-11-18 15:21 | 显示全部楼层
Code
  1. //通用定时器 3 中断初始化
  2. //arr:自动重装值。 psc:时钟预分频数
  3. //定时器溢出时间计算方法:Tout=((arr)*(psc))/Ft us.
  4. //Ft=定时器工作频率,单位:Mhz
  5. //这里使用的是定时器 3!
  6. void TIM3_Int_Init(u16 arr,u16 psc)
  7. {
  8. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  9. NVIC_InitTypeDef NVIC_InitStructure;

  10. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能 TIM3 时钟

  11. TIM_TimeBaseInitStructure.TIM_Period = arr-1; //自动重装载值
  12. TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1; //定时器分频
  13. TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
  14. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

  15. TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);// 初始化定时器 TIM3

  16. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器 3 更新中断

  17. NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器 3 中断
  18. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级 1
  19. NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //响应优先级 3
  20. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  21. NVIC_Init(&NVIC_InitStructure);// 初始化 NVIC

  22. TIM_Cmd(TIM3,ENABLE); //使能定时器 3

  23. //定时器 3 中断服务函数
  24. void TIM3_IRQHandler(void)
  25. {
  26. if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
  27. {
  28.         PPS_OUT=1;
  29.         delay_ms(100);       
  30.         PPS_OUT=0;
  31. }
  32. TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
  33. }
 楼主| lxs0026 发表于 2022-11-18 15:22 | 显示全部楼层
包含一个中断服务函数和一个定时器 3 中断初始化函数

该函数的 2 个参数用来设置TIM3 的溢出时间。因为系统初始化 SystemInit 函数里面已经初始化 APB1 的时钟为 4 分频,所
以 APB1 的时钟为 42M,

当 APB1 的时钟分频数为 1 的时候,TIM2-7 以及 TIM12-14 的时钟为 APB1 的时钟,而如果 APB1 的时钟分频数不为 1,那么 TIM2-7 以及 TIM12-14 的时钟频率将为 APB1 时钟的两倍。因此,TIM3 的时钟为 84M,再根据设计的 arr 和 psc 的值,就可以计算中断时间了。
 楼主| lxs0026 发表于 2022-11-18 15:22 | 显示全部楼层
计算公式如下:

Tout= ((arr+1)*(psc+1))/Tclk;
 楼主| lxs0026 发表于 2022-11-18 15:23 | 显示全部楼层
其中:
Tclk:TIM3 的输入时钟频率(单位为 Mhz)。
Tout:TIM3 溢出时间(单位为 s)。

然后在中断函数中,判断发生中断后,拉高AF10,延时100ms再拉低。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部