STM32学习笔记(2):通用定时器中断

说明

此篇作为学习笔记,如有错误还请评论指出。

正篇

STM32单片机的定时器资源:
在这里插入图片描述
(图片来源正点原子B站教程)
这里是主要针对通用定时器的笔记。

STM32通用定时器的特点:
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。
它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和
PWM)。
使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。
每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。

通用定时器的时钟来源有三:默认内部时钟CK_INT,外部输入引脚(TIx),外部触发引脚(ETR)。一般情况下,选择默认。
在这里插入图片描述
(图片来源正点原子B站教程)
从上图中可以看出,在默认情况下,定时器的时钟是来自APB1时钟的,假如APB1时钟分频系数为一那么CK_INT时钟就是APB1时钟,假如APB1分频系数不为一,那么CK_INT时钟就是分频后乘二得来。

通用定时器的计数模式:
分为三种:
1、向上计数模式:计数器从零开始计数到自动重装载值(TIMx_arr),然后重新从零开始计数并且产生一个计数器溢出时间(若中断开启则发生中断)。
2、向下计数模式:计数器开始从自动重装载值(TIMx_arr)向下计数到零,然后重新从自动重装载值计数并且产生一个计数器溢出事件(若中断开启则发生中断)。
3、中央对齐模式(向上/向下计数):计数器从零开始计数到自动装载值-1产生一个计数器溢出事件,然后向下计数到一并且产生一个计数器溢出事件,然后再从零开始重新计数。

自动重装载值arr和预分频系数psc
自动重装载值arr保存在自动重装载寄存器TIMx_ARR
在这里插入图片描述

TIMx_ARR是一个十六位的寄存器,很好理解,就是定时器定时到某一个值的时候就是开始下一个周期,但是使用时注意不要超过寄存器的最大值。

预分频系数保存在预分频器中
在这里插入图片描述
预分频器TIMx_PSC类似于自动重装载值寄存器,同样为十六位寄存器。但是预分频系数需要一定的理解。直接以向上计数模式来举例。
在这里插入图片描述
在这里插入图片描述
比较上面两图,内部时钟分频因子就是(预分频系数 + 1),发现CK_CNT(定时器当前值寄存器),计数的间隔变大了,当PSC= 1时,CK_INT和CK_CNT变化是同步的,CK_INT每变化一次,CK_CNT就变化一次,计数器寄存器就加一,但是当PSC = 2时,CK_INT和CK_CNT变化不再同步了,当CK_INT变化两次时,CK_CNT变化一次,计数器寄存器加一。这就是预分频系数PSC的作用,这样就可以实现定时器计时最小值可以是微秒也可以是毫秒级的。
假如说时钟是72MHz,那么我们要是想延时500ms,就可以配置psc为7199(psc+1才是时钟分频因子) arr为499(arr也要加一)这样计数器寄存器每加一一次就是定时1ms计数500就是500ms,psc和arr的值并不是固定的,只要算出来的数在允许范围内都是可以的。
在这里插入图片描述
这一位在在这里插入图片描述中,也应特别注意一下。
接着举例。
在这里插入图片描述
在这里插入图片描述
仍然是比较上面两图,在ARPE = 0时,当arr改变时,若定时器当前值为达到改变后的arr值,计数到改变后的arr值时,中断发生,当ARPE = 1时,arr发生改变,那么就会在此次中断发生之后生效,下一次中断在定时器计数到改变后的arr值时发生。
区别就是arr改变时什么时候生效,ARPE = 0立即生效,ARPE = 1下个周期生效。(这里过程比较复杂,不再细说)

**

通用定时器中断一般实现步骤:

**
1、使能定时器时钟
通用定时器挂载在APB1总线下故使能APB1时钟。
2、初始化定时器,配置arr和psc
注意:arr和psc都是要 + 1后起作用的。
3、开启定时器中断,配置NVIC
4、使能定时器
5、编写中断服务函数

#include "stm32f10x.h"
#include "LED.h"
#include "TIMER.h"

void Timer3_Int_Init(unsigned int arr, unsigned int psc)
{
	//定时器初始化结构体参数
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//中断优先级初始化结构体参数
	NVIC_InitTypeDef NVIC_InitStructure;
	
	
	//使能APB1总线时钟 使能定时器3时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	
	//参数在此实验无意义
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	//设置定时器工作模式为向上模式
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//定时器3重设初值为人为给予
	TIM_TimeBaseInitStructure.TIM_Period = arr;
	//定时器3预分频数为人为给予
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
	
	
	//初始化定时器3
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//使能定时器3 并设置为事件更新
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	
	//中断通道为定时器3
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	//使能该中断
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//设置抢占优先级为1
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	//设置响应优先级为1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	
	//初始化中断
	NVIC_Init(&NVIC_InitStructure);
	//使能定时器
	TIM_Cmd(TIM3, ENABLE);
}

void TIM3_IRQHandler()
{
		//判断是否为定时器3中断
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
	{
		LED1 = ~LED1;
		//清除定时器中断标志位
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}


结语

简单的通用定时器知识与配置已经记录完了,后续可能会有深度详细的补充。
若有错误,还请评论指出。
共同进步。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ydon?tkwhmeIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值