stm32 定时器中断

在上一篇 STM32外部中断的理解 中,我们讲述了stm32的外部中断,它是通过外部的一个中断信号作为中断源,对 CPU 进行申请中断处理的;此篇,我们再讲述下 stm32 的内部定时器中断。

1. 综述

stm32 定时器中断,是通过设置内部的定时器相关寄存器,然后定时器进行自增(自减)到某一个数之后,产生一个中断信号,由 cpu 进行处理。如下图:

其中,时基单元部分相关的寄存器就是我们需要设置的。

下图是基本定时器框图:

2. 名词解析

CK_PSC : 定时器的预分频器时钟源。这个值为系统时钟频率,在手册中,虽然 TIM2 是属于 APB1 外设,APB1 外设的时钟频率为36MHz,但是我们使用的库中,在 SystemInit 函数中,将所有的定时器都倍频到了72MHz,所以这个值为72MHz。
PSC : 定时器的预分频器寄存器(Prescaler Register)。在 stm32 中,预分频器用于将定时器的时钟源分频,以降低定时器的时钟频率。
CK_CNT : 定时器计数器的时钟源。CK_CNT = CK_PSC / (PSC + 1)
CNT : 定时器的计数器寄存器。用于记录定时器的计数值,根据定时器的时钟源逐渐递增或递减,计数器增加达到最大值时会自动重置为0,并触发相应的中断事件。CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)

ARR: 自动重装载寄存器(Auto-Reload Register)

3. 源码解析

我们这个实例演示了,通过定时器每隔1秒产生一个中断,并在 OLED 屏幕上进行显示。要达到这个功能,主要的核心是设置好 PSCARR

源码:

复制代码
#include "Timer.h"

uint16_t num = 0;

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	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_FLAG_Update);
	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	
	TIM_Cmd(TIM2, ENABLE);
}

uint16_t Timer_Get(void)
{
	return num;
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
		num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
3.1 使能 TIM2 外设时钟
复制代码
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

TIM2 属于 APB1 外设。

3.2 配置时钟源
复制代码
TIM_InternalClockConfig(TIM2);

TIM2 作为内部时钟源,并且时钟频率是72MHz。若不调用此函数,TIM默认也为内部时钟

3.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;					// 计数周期,即 ARR 的值
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;				// 预分频器,即 PSC 的值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;				// 重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

ARR: 10000 - 1, PSC:7200 - 1, 此时我们可以计算出计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)

CK_CNT_OV = 72MHz/(7200 - 1 + 1)/(10000 - 1 + 1) = 1 Hz

即:1秒产生1次溢出

预分频器确定好后,我们就可以通过设置 ARR 值,来产生不同时间的定时器。

3.4 开启TIM2的更新中断
复制代码
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);	
3.5 配置 NVIC
复制代码
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);

具体的解释参考:STM32外部中断的理解

3.6 TIM 使能
复制代码
TIM_Cmd(TIM2, ENABLE);

使能TIM2,定时器开始运行

3.7 中断处理
复制代码
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
		num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

至此,基本上整个定时器中断的流程就解析完成了。

引用:
https://blog.uwenya.cc/1320.html

相关推荐
得单片机的运3 小时前
STM32的蓝牙通讯(HAL库)
stm32·单片机·嵌入式硬件·蓝牙
国科安芯4 小时前
抗辐照芯片在低轨卫星星座CAN总线通讯及供电系统的应用探讨
运维·网络·人工智能·单片机·自动化
weixin_452600695 小时前
GC8872刷式直流电机驱动器详解:3.6A驱动能力与PWM控制
stm32·单片机·嵌入式硬件·智能家居·音响·电动工具
Despacito0o8 小时前
STM32 I2C通信完整教程:从协议原理到硬件实现
stm32·单片机·嵌入式硬件
你好,奋斗者!8 小时前
小电流驱动大电流:原理、实现方式与应用前景
stm32·单片机·嵌入式硬件·电路设计
XINVRY-FPGA11 小时前
XCZU4EV-1FBVB900E Xilinx FPGA AMD Zynq UltraScale+ MPSoC EV(Embedded Vision)
arm开发·嵌入式硬件·计算机视觉·fpga开发·硬件架构·硬件工程·fpga
猫猫的小茶馆12 小时前
【STM32】FreeRTOS 任务的删除(三)
java·linux·stm32·单片机·嵌入式硬件·mcu·51单片机
学不动CV了12 小时前
单片机ADC采集机理层面详细分析(二)
c语言·arm开发·stm32·单片机·嵌入式硬件·开源·51单片机
学不动CV了12 小时前
51核和ARM核单片机OTA实战解析(二)
c语言·arm开发·stm32·单片机·嵌入式硬件·51单片机
Yuroo zhou13 小时前
IMU的精度对无人机姿态控制意味着什么?
单片机·嵌入式硬件·算法·无人机·嵌入式实时数据库