定时器中断流程讲解,结合代码

本文重点在于记录和理解定时器中断的流程,关于定时器和中断的知识点不过多赘述,相关知识点可以查看我的另外两篇文章,讲的很详细,希望能有所帮助。

定时器:
STM32定时器和时钟树详细图文讲解,小白必会!-CSDN博客

外部中断:
STM32外部中断讲解-CSDN博客

下图为用内部时钟作时钟源的定时器中断流程,标了执行逻辑的顺序。

  1. RCC时钟使能,开启APB1总线上的TIM2时钟(TIM2,3,4,5为通用定时器)
    // 1. RCC时钟使能
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  2. 选择时基单元(预分频器,计数器,自动重装器)的时钟源
    // 2. 选择时基单元的时钟源
    TIM_InternalClockConfig(TIM2); 

    选择内部时钟,连接到使用的TIM2通用定时器。

  3. 配置时基单元
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; // 定义结构体
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 滤波器分频,设为不分频
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
    TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1; // 自动重装器
    TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; // 预分频器
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; // 高级定时器的重复计数器
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); // 初始化时基单元

    TIM_TimeBaseInitStruct结构体包含了时基单元的配置,最后初始化别忘了取值符&

  4. 中断输出控制
    // 开启更新中断到NVIC的通路,更新中断就是计数溢出产生的,表明定时器定的时间到了
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    在3到4这个过程中间,中断信号会在状态寄存器里置一个中断标志位,这个标志位会通过中断输出控制到NVIC申请中断。
    为什么要有中断输出控制呢?
    因为定时器还有很多模块都需要申请中断,比如不仅计数器重新置零会触发中断,触发信号也会申请中断,输入捕获和输出比较也会申请中断,所有这些中断都需要经过输出中断控制。如果需要就允许,不需要就禁止,简单来说中断输出控制就是一个中断输出的允许位,如果需要某个中断就允许一下

  5. 中断分组,配置和初始化NVIC
    // 5. 中断分组
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
    
    // 配置和初始化STM32中断控制器(NVIC)
    NVIC_InitTypeDef NVIC_InitStrucyure;
    NVIC_InitStrucyure.NVIC_IRQChannel = TIM2_IRQn; //指定中断请求通道。
    NVIC_InitStrucyure.NVIC_IRQChannelCmd = ENABLE; //启动指定的通道
    NVIC_InitStrucyure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
    NVIC_InitStrucyure.NVIC_IRQChannelSubPriority = 1; //响应优先级
    NVIC_Init(&NVIC_InitStrucyure);

    在配置NVIC结构体前先进行中断分组。

  6. 使能计数器
    // 6.运行控制,使能计数器
    TIM_Cmd(TIM2, ENABLE); 
  7. 自动调用中断函数

   

完整代码如下,值得注意的是定时器初始化后会自动触发一个事件,不等计数器就立马触发中断,所以得加个清除标志位

void Timer_Init(void) 
{
	// 1. RCC时钟使能
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	// 2. 选择时基单元的时钟源
	TIM_InternalClockConfig(TIM2); 
	// 3. 配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 滤波器分频,设为不分频
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1; // 自动重装器
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; // 预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; // 高级定时器的重复计数器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //  初始化时基单元

	// 实际单元初始化会产生中断事件,不等计数器就立马触发中断,所以清除标志位
	TIM_ClearFlag(TIM2, TIM_IT_Update); 

	// 4. 中断输出控制
	// 开启更新中断到NVIC的通路,更新中断就是计数溢出产生的,表明定时器定的时间到了
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	// 5. 中断分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	// 配置和初始化STM32中断控制器(NVIC)
	NVIC_InitTypeDef NVIC_InitStrucyure;
	NVIC_InitStrucyure.NVIC_IRQChannel = TIM2_IRQn; //指定中断请求通道。
	NVIC_InitStrucyure.NVIC_IRQChannelCmd = ENABLE; //启动指定的通道
	NVIC_InitStrucyure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
	NVIC_InitStrucyure.NVIC_IRQChannelSubPriority = 1; //响应优先级
	NVIC_Init(&NVIC_InitStrucyure);
	// 6.运行控制,使能计数器
	TIM_Cmd(TIM2, ENABLE); 

	// 7. 之后自动调用中断函数
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值