STM32学习笔记(4)

文章详细介绍了STM32中的定时器功能,包括基本定时中断、输出比较(PWM)、输入捕获和编码器接口。通过配置预分频器、计数器和自动重装寄存器实现不同定时任务,并提供了初始化定时器的步骤。此外,还提到了通用定时器的外部时钟模式和高级定时器的重复计数器及死区生成功能。
摘要由CSDN通过智能技术生成

STM32中功能最强大,结构最复杂的外设——定时器

第一部分,我们主要讲的时定时器的基本定时功能,也就是定一个时间,然后让定时器每个一段时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做时钟、秒表、或者使用一些程序算法的时候,都需要用到定时中断这个功能。

第二部分,我们主要讲的是定时器输出比较的功能,输出比较这个模块最常见的用途是产生PWM波形,用于驱动电机等设备,使用STM32输出的PWM波形来驱动舵机和直流电机的例子

第三部分,我们主要讲的是定时器输入捕获的功能,在这个部分,我们将会学习使用捕获这个模块来实现测量方波频率的例子。

第四部分,我们学习定时器的编码器接口,使用这个编码器接口,能更加方便的读出正交编码器输出波形,在编码电机测速中,应用非常广泛。

TIM(Timer)定时器

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断,换句话来说,定时器就是一个计数器。
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

时基单元:(均是16位)
计数器就是用来执行计数定时的一个寄存器,每来一个时钟,计数器加1
预分配器,可以对计数器时钟进行分频,让这个计数器更加灵活
自动重装寄存器就是计数的目标值,就是我想要记多少个时钟申请中断

定时器类型

请添加图片描述

基本定时器

在这里插入图片描述
预分频器、计数器、自动重装载寄存器构成了最基本的计数计时电路,所以这一块电路就叫做时基单元
通向时基单元的计数基准频率是72M
预分频器:可以对72MHz的计数时钟进行预分频,比如寄存器写0,那就是不分频,或是1分频,这时候输出频率 = 输入频率 = 72MHz,如果预分频器写1,那就是2分频,输出频率=输入频率/2 = 36MHz,以次类推,实际分频系数 = 预分频器的值+1
计数器:计数时钟没来一个上升沿,计数器的值+1,计数器的值会不断的自增运行,当自增运行到目标值时,产生了中断,那就完成了定时的任务。
自动重装寄存器:自动重装寄存器也是16位,它存的就是我们写入的计数目标,在运行的过程中,计数值不断自增,自动重装讲的值时固定的目标,当计数值等于自动重载值时,也就是计时时间到了,他就会产生一个中断信号,并且清零计数器,计数器开始下一次的计数计时,同时产生中断信号,称为更新中断,更新中断 之后就会通往NVIC。在使用DAC的时候,可能会用DAC输出一段波形,定时器在这里设置了一个主模式,使用这个主模式,可以把这个定时器更新事件,映射到这个触发输出TRGO(Trigger Out)的位置,然后直接接到DAC的触发转换引脚上,仅需要把更新时间通过主模式映射到TRGO,然后TRGO就会直接去触发DAC

通用定时器

在这里插入图片描述
在通用计时器中,这个计数器的计数模式就不止向上计数这一种了,向上计数:计数器从0开始,向上自增,寄到重装值,清零同时申请中断,然后开始下一轮,一次循环,这是向上计数。
通用计时器中,时钟源不仅可以选择内部的72MHz时钟,还可以选择外部时钟,第一个外部时钟就是来自TIMx_ETR引脚上的外部时钟。另外一个就是TRGI(Trigger In)用作触发输入来使用,触发输入可以触发定时器的从模式,在这里我们探讨触发作为外部时钟来使用的情况。
外部时钟模式1的输入可以是ETR引脚、其他定时器、CH1引脚的边沿,CH1引脚和CH引脚
编码器接口:可以读取正交编码器的输出波形
这个就是定时器的主模式输出,可以把内部的一些事件,映射到这个TRGO引脚上
输出比较电路:分别对应CH1~CH4的引脚,可以用于输出PWM波形,驱动电机
输入捕获电路:对应CH1~CH4的引脚,可以测量方波的频率等
捕获/比较寄存器:是输入捕获和输出比较电路共用的,因为输入捕获和输出捕获比较不能同时使用,所以这里的寄存器是公用的,引脚也是公用的

高级定时器

在这里插入图片描述
在申请中断的地方,增加了一个重复次数计时器,有了这计数器,就可以实现每隔几个计数周期,才发生一次事件更新和更新中断
DTG(Dead Time Generate)死区生成电路:
右边的输出引脚变为了两个互补输出,可以输出一对互补的PWM波,可以驱动三相无刷电机,
刹车输入:给电机驱动提供安全保障的

定时中断基本结构

请添加图片描述

预分频器时序

在这里插入图片描述
计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

计数器时序

在这里插入图片描述
计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
= CK_PSC / (PSC + 1) / (ARR + 1)

计数器有预装时钟

在这里插入图片描述
更加严谨,让值的变化和更新事件同步发生,防止在运行途中更改造成错误

RCC时钟树

在这里插入图片描述

初始化定时器步骤

第一步 RCC开启时钟
第二步 选择时基单元的时钟源
第三步 配置时基单元,包括预分配器,自动重装器,计数模式等等,这些参数用一个结构体就可以配置好了
第四步 配置输出中断控制,允许更新中断输出到NVIC
第五步 配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
第六步 运行控制,整个模块配置完成后,还要使能一下计数器,不然计数器不会运行,当是能计数器后,计数器就会开始技术了,当计数器更新时,触发中断,最后写定时器中断函数,这样中断函数每隔一段时间就能自动执行一次了

TIM函数

TIM_DeInit 恢复缺省配置
TIM_TimeBaseInit 时基单元初始化
TIM_TimeBaseStructInit 把结构体变量赋一个默认值
TIM_Cmd 用来使能计数器
TIM_ITConfig 使能中断输出信号的
TIM_InternalClockConfig 选择内部时钟
TIM_ITRxExternalClockConfig 选择ITRx其他定时器的时钟
TIM_TIxExternalClockConfig 选择TIx捕获通道的时钟
TIM_ETRClockMode1Config 选择ETR通过外部时钟模式1输入的时钟
TIM_ETRClockMode2Config 选择ETR通过外部时钟模式2输入的时钟
TIM_ETRConfig 用来配置ETR引脚的预分频器,极性,滤波器这些参数的
TIM_PrescalerConfig 用来单独写预分频值
TIM_CounterModeConfig 用来改变计数器的计数模式
TIM_ARRPreloadConfig 自动重装器预装功能配置
TIM_SetCounter 给计数器写入一个值
TIM_SetAutoreload 给自动重装器写入一个值
TIM_GetCounter 获取当前计数器的值
TIM_GetPrescaler 获取当前的预分频器的值

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   // 使用APB1开启时钟函数
	
	TIM_InternalClockConfig(TIM2); // 选择TIM2作为时基单元的时钟源
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSturct;	//配置结构体
	TIM_TimeBaseInitSturct.TIM_ClockDivision = TIM_CKD_DIV1;  //指定时钟分频
	TIM_TimeBaseInitSturct.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式
	TIM_TimeBaseInitSturct.TIM_Period = 10000 - 1; //ARR自动重装器
	TIM_TimeBaseInitSturct.TIM_Prescaler = 7200 - 1; //PSC预分配频的值
	TIM_TimeBaseInitSturct.TIM_RepetitionCounter = 0; //重复计数器的值
	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitSturct); // 配置时基单元
	
	TIM_ClearFlag(TIM2, TIM_IT_Update); //手动清除更新中断标志位, 避免刚初始化完就进入中断的问题 (从0开始)
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能更新中断  更新中断到NVIC的通路
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	
	//  NVIC优先级分组
	NVIC_InitTypeDef NVIC_InitStructrue;    
	NVIC_InitStructrue.NVIC_IRQChannel = TIM2_IRQn; // 定时器2在NVIC里的通道
	NVIC_InitStructrue.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
	NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 1; // 响应优先级
	NVIC_Init(&NVIC_InitStructrue);
	
	//启动定时器
	TIM_Cmd(TIM2, ENABLE);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lucky Ray

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

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

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

打赏作者

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

抵扣说明:

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

余额充值