STM32 TIM定时中断设计

单片机学习

目录

文章目录

一、定时器定时中断设计步骤

二、定时器配置

1.RCC开启时钟

2.选择时钟源

3.配置时基单元

4.配置输出中断控制

5.配置NVIC

6.运行控制

三、设计中断函数

总结


一、定时器定时中断设计步骤

定时中断基本框架结构图:

根据结构图可按步骤配置定时器

第1步:RCC开启时钟。打开时钟后定时器的基准时钟和整个外设的工作时钟就会同时打开。

第2步: 选择时基单元的时钟源。对于定时中断可选择内部时钟源.

第3步: 配置时基单元,包括预分频器、自动重装器、计数模式等,这些参数可用结构体配置。

第4步: 配置输出中断控制,允许更新中断输出到NVIC。

第5步: 配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级。

第6步:运行控制,整个模块配置完成后,还需要使能一下计数器,不使能计数器,计数器是不会运行的。当定时器使能后,计数器就会开始计数了;当定时器更新时,触发中断。

第7步: 设计一个中断函数,中断函数每隔一段时间就自动执行一次。

二、定时器配置

文章举例初始化通用定时器中的TIM2定时器。

1.RCC开启时钟

RCC开启时钟。打开时钟后定时器的基准时钟和整个外设的工作时钟就会同时打开。因为TIM2是APB1总线外设,所以要使用APB1的开启时钟函数。开启时钟要注意总线的函数选择。

代码示例:

c 复制代码
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//使用APB1的开启时钟函数,因为TIM2是APB1总线的外设。

2.选择时钟源

选择时基单元的时钟源。对于定时中断可选择内部时钟源。

代码示例:

c 复制代码
	TIM_InternalClockConfig(TIM2);
//定时器上电后默认使用内部时钟,若不调用这个函数,也是使用内部时钟,有时可省略

定时器上电后默认使用内部时钟,若不调用这个函数,也是使用内部时钟,有时这个函数可省略。

3.配置时基单元

配置时基单元,包括预分频器、自动重装器、计数模式等,这些参数可用结构体配置。

代码示例:

	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision= TIM_CKD_DIV1;//指定时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode= TIM_CounterMode_Up;//计数器模式
	TIM_TimeBaseInitStructure.TIM_Period= 10000-1;//ARR自动重装器的值,决定定时时间
	TIM_TimeBaseInitStructure.TIM_Prescaler= 7200-1;//PSC预分频器的值,决定定时时间,
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0;//重复计数器的值。
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

结构体成员:

  • TIM_ClockDivision:指定时钟分频,用于信号经过滤波器时的滤波采样频率。
  • TIM_CounterMode:计数器模式,这里选择向上计数模式TIM_CounterMode_Up。
  • TIM_Period :ARR自动重装器的值。
  • TIM_Prescaler:PSC预分频器的值。
  • TIM_RepetitionCounter:重复计数器的值,只有高级定时器才有,本文初始化通用寄存器,所以值给0。

时基单元中关键寄存器参数ARR、PSC都有设置,但是这里没有CNT计数器的参数,CNT参数的配置可更具需要在函数 TIM_SetCounter 和函数 TIM_GetCounter 中操作。

决定定时时间的参数是 TIM_Period 和 TIM_Prescaler 。定时时间可用计数器溢出频率公式计算,**定时频率=72M/(PSC+1)/(ARR+1)。**定时1秒,也就是定时频率为1Hz。示例中预分频是对72M进行7200分频,得到的就是10K的计数频率。在10K的频率下,计10000个数,就是1s的时间。

TIM_Period 和 TIM_Prescaler参数的取值不是唯一的,

  • 可以预分频器给少点,自动重装器给多点,这样就是以一个较高的频率计比较多的数。
  • 可以预分频器给多点,自动重装器给少点,这样就是以一个较低的频率计比较少的数。

这两种方法都可以达到目标的定时时间。因为预分频器和计数器都有1个数的偏差,所以PSC和ARR两个值都要再减1,PSC和ARR的取值都要在0~65535之间,不能超范围。

TIM_TimeBaseInit函数调用,更新事件和更新中断是同时发生的,更新中断会置更新标志位。就导致TIM初始化完后更新中断就会立刻进入。

解决方案:在TIM_TimeBaseInit函数后,开启中断前添加TIM_ClearFlag函数。

cpp 复制代码
TIM_ClearFlag(TIM2,TIM_FLAG_Update);

4.配置输出中断控制

配置输出中断控制,允许更新中断输出到NVIC。

代码示例:

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

函数开启了更新中断到NVIC的通路。

5.配置NVIC

配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级。

代码示例:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStructure);

NVIC配置具体看之前博客STM32 外部中断配置与中断函数设计-CSDN博客

6.运行控制

运行控制,整个模块配置完成后,还需要使能一下计数器,不使能计数器,计数器是不会运行的。当定时器使能后,计数器就会开始计数了;当定时器更新时,触发中断。

代码示例:

TIM_Cmd(TIM2,ENABLE); 

三、设计中断函数

设计一个中断函数,中断函数每隔一段时间就自动执行一次。

代码示例:

cpp 复制代码
void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
    {
        //中断执行代码
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了定时器中断配置和对应中断函数的设计。

相关推荐
Zevalin爱灰灰31 分钟前
编程技巧(基于STM32)第一章 定时器实现非阻塞式程序——按键控制LED灯闪烁模式
stm32·单片机·嵌入式硬件
红花与香菇2____2 小时前
【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(上)
笔记·嵌入式硬件·学习·pcb设计·cadence·pcb工艺
Jerry.yl2 小时前
关于 BK3633 上电时受串口 UART2 影响而无法启动的问题说明
嵌入式硬件·物联网·bk3633
苏慕TRYACE4 小时前
RT-Thread+STM32L475VET6实现红外遥控实验
stm32·单片机·嵌入式硬件·rt-thread
小幽余生不加糖5 小时前
deepseek帮我设计物理量采集单片机口保护电路方案
单片机·嵌入式硬件
Ronin-Lotus6 小时前
蓝桥杯篇---IAP15F2K61S2串口
单片机·嵌入式硬件·职场和发展·蓝桥杯·c·iap15f2k61s2
xiaohai@Linux7 小时前
ESP32 在IDF_V5.3.1版本下实现AP无线热点模式!(带WIFI事件处理)
c语言·嵌入式硬件·tcp/ip·wifi·esp32
yyqzjw8 小时前
【STM32】外部时钟|红外反射光电开关
stm32·单片机·嵌入式硬件
charlie1145141918 小时前
(萌新入门)如何从起步阶段开始学习STM32 —— 0.碎碎念
c语言·stm32·单片机·嵌入式硬件·学习·教程
苏慕TRYACE8 小时前
RT-Thread+STM32L475VET6——ADC采集电压
stm32·单片机·嵌入式硬件·rt-thread