032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识

2023-12-24 00:45

本文主要是介绍032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

032 - STM32学习笔记 - TIM定时器(一) - 基本定时器知识

在这里插入图片描述

这节开始学习一下TIM定时器功能,从字面意思上理解,定时器的基本功能就是用来定时,与定时器相结合,可以实现一些周期性的数据发送、采集等功能,比如定时发送USART数据、ADC定时采集数据、与GPIO结合测量信号输入脉宽以及产生输出波形,常用的PWM波控制电机就是定时器的一种应用。

在STM32F42xxx系列控制器中,有2个高级控制定时器、10个通用定时器和2个基本定时器以及2个看门狗定时器。控制器上所有定时器都是彼此独立,不共享任何资源。高级控制定时器包含通用定时器的所有功能,通用定时器包含基本定时器的所有功能。其特性参见下表:

定时器类型Timer计数器分辨率计数器类型预分频系数DMA请求生成捕获/比较通道互补输入最大接口时钟(MHz)最大定时器时钟(MHz)
高级控制TIM116位递增、递减、递增/递减1~65536490(APB2)180
通用TIM232位递增、递减、递增/递减1~65536445(APB1)90/180
通用TIM316位递增、递减、递增/递减1~65536445(APB1)90/180
通用TIM416位递增、递减、递增/递减1~65536445(APB1)90/180
通用TIM532位递增、递减、递增/递减1~65536445(APB1)90/180
基本TIM616位递增1~65536045(APB1)90/180
基本TIM716位递增1~65536045(APB1)90/180
高级控制TIM816位递增、递减、递增/递减1~65536490(APB2)180
通用TIM916位递增1~65536290(APB1)180
通用TIM1016位递增1~65536190(APB1)180
通用TIM1116位递增1~65536190(APB1)180
通用TIM1216位递增1~65536245(APB1)90/180
通用TIM1316位递增1~65536145(APB1)90/180
通用TIM1416位递增1~65536145(APB1)90/180

这里需要注意,所有定时机器预分频系数都是在1~65536之间取值,且都为整数。最大定时器时钟可以通过RCC_DCKCFGR寄存器进行配置,可配置值为90/180MHz。

一、基本定时器功能框图

基本定时器的功能框图包含了基本定时器最核心的内容,其结构如下图:

在这里插入图片描述

在上图中,绿框中是对定时器的图标解释,黑框带阴影方框中,方框内容一般为寄存器名称,比如上面的自动重载寄存器(TIMx_ARR)和PSC(TIMx_PSC)预分频寄存器,方框加阴影效果主要是为了突出表示该寄存后面还有一个寄存器,只是这个寄存器我们无法进行操作,这里我们称之为影子寄存器,而上面我们可以操作的寄存器我们称之为源寄存器。影子寄存器是在程序运行时真正起到作用的,源寄存器只是给我们提供读写功能,当特定事件发生时,才会把源寄存器的值拷贝给其影子寄存器。多个影子寄存器一起使用可以达到同步更新多个寄存器内容。

下面向下趋势的折线箭头表示为一个事件,向上趋势的这下箭头表示中断和DMA输出,以上图为例,在自动重载寄存器左侧带有字母“U”的是按图标,表示在更新事件生成时就把自动重载寄存器内容拷贝到影子寄存器内,寄存器右边的时间图标、中断和DMA输出图标表示在自动重载寄存器与计数器寄存器值相等时生成事件、中断和DMA输出。

在了解图示图标后,下来我们逐项分析下基本定时器框图:

1、时钟源

既然要实现定时的功能,就必须要给定时器提供时钟源实现计数,基本定时器时钟只能使用内部时钟,而高级和通用定时器可以选择外部时钟源或者其他定时器等待模式。可以通过RCC专用始终配置寄存器(RCC_DCKCFGR)的TIMPRE位设置所有定时器的时钟频率,一般改为设置为默认值0。从而使得上面表中的可选最大定时器时钟为90MHz,即基本定时器的内部时钟CK_INT频率为90MHz。

基本定时器只能使用内部时钟,当TIM6和TIM7控制寄存器1(TIMx_CR1)的GEN位置1时,启动基本定时器,并且预分频器的始终来源位CK_INT。

2、控制器

控制器用于控制实现定时器功能,控制其复位、使能、计数等其基础功能,基本定时器还专门用于DAC转换触发。

3、计数器

基本定时器计数过程中主要针对三界寄存器,分别位计数器寄存器TIMx_CNT、预分频器寄存器TIMx_PSC、自动重载寄存器TIMx_ARR,这三个寄存器均为16位有效位,可以设置的值为0~65535。

预分频寄存器PSC:预分频器PSC有一个输入时钟CK_PSC和一个输出时钟CK_CNT,输入时钟CK_PSC来源于控制器,基本定时器只有内部时钟源,所以CK_PSC实际等于CK_INT,即90MHz。当需要不同的定时频率时,可以通过设置预分频器PSC的值可以得到不同的时钟输出CK_CNT,计算公式如下:
f C K C N T = f C K P S C / ( P S C [ 15 : 0 ] + 1 ) fCKCNT = fCKPSC/(PSC[15:0]+1) fCKCNT=fCKPSC/(PSC[15:0]+1)
在这里插入图片描述

上图中明确表示了将预分频从1改为4时计数器变化过程,在1分频时,CK_PSC和CK_CNT频率相同。向TIMx_PSC寄存器写入新值时,并不会马上更新CK_CNT的输出频率,需要等到更新事件发生时,把TIMx_PSC寄存器值更新到影子寄存器中,才能产生效果。当更新为4分频后,CK_PSC每产生4个脉冲时,CK_CNT才会产生1个脉冲。

当定时器使能时(CNT_EN = 1),计数器COUNTER根据CK_CNT的频率向上计数,意思就是当CK_CNT每产生一个脉冲,TIMx_CNT的值就累加1。当TIMx_CNT的值与TIMx_ARR的值一致时会自动生成事件,并且TIMx_CNT自动清零,然后开始下一轮计数,如此往复。

因此我们只需要设置CK_PSC和TIMx_ARR这两个寄存器的值,就可以控制事件生成的事件,一般的应用程序就是在事件生成的会点函数中运行,在TIMx_CNT递增至TIMx_ARR值相等时,我们称之为定时器上溢。

自动重载寄存器TIMx_ARR用于存放与计数器值比较的数值(设定值),如果两个数值相等就生成事件,将相关事件标志位置位,生成DMA和中断输出。TIMx_ARR有影子寄存器,可通过RIMx_CR1寄存器的ARPE位控制影子寄存器功能,如果ARPE位置1,影子寄存器有效,当且只有事件更新时,才会将TIMx_ARR值赋值给影子寄存器,如果ARPE位为0,修改TIMx_ARR值则可以马上生效。

4、定时器周期计算

通过上面的内容,我们直到定时时间生成时间主要由TIMx_PSC和TIMx_ARR两个寄存器值决定,这个称之为定时器的周期。假如我们需要一个1s周期的定时器,该如何设置这两个寄存器的值呢?

假设我们先设置TIMx_ARR寄存器的值为9999,则表示当TIMx_CNT从0开始计数,当累加到9999个脉冲后,生成事件,合计就是10000次,那么如果此时时钟源周期为100us,就刚好得到了1s的定时周期。

如此我们只需要关注如何设置TIMx_PSC寄存器值,使得CK_CNT输出为100us(1/0.0001 = 10000Hz)周期的时钟即可。预分频的输入时钟CK_PSC为90Mhz,根据上面提供的CK_CNT计算公式得到PSC = 90MHz / 10000Hz - 1 = 9000 - 1 = 8999。

OK,定时器的基本内容学习完了,下来就是了解一下与定时器相关的结构体了。

二、定时器相关结构体

标准库中对定时器外设建立了四个初始化结构体,其中基本定时只用到一个,即TIM_TimeBaseInitTypeDef,该结构体成员用于设置定时器基本工作参数,并由定时器基本初始化配置函数TIM_TimeBaseInit调用。

TIM_TimeBaseInitTypeDef结构体定义在stm32f4xx_tim.h中,TIM_TimeBaseInit函数定义在stm32f4xx_tim.c中,首先我们先看一下TIM_TimeBaseInitTypeDef结构体定义:

typedef struct {uint16_t TIM_Prescaler; 			// 预分频器uint16_t TIM_CounterMode; 			// 计数模式uint32_t TIM_Period; 			    // 定时器周期uint16_t TIM_ClockDivision; 		// 时钟分频uint8_t TIM_RepetitionCounter; 		// 重复计算器
} TIM_TimeBaseInitTypeDef;

定时器预分频器TIM_Prescaler:时钟源经过该分频器之后输出的才是定时器时钟,该值设置的为TIM_PSC寄存器的值,可设置范围为065535,可实现165536分频。

定时器计数模式TIM_CounterMode:可视之为向上计数、向下计数以及三种中心对其模式,基本定时器只能为向上计数,即TIMx_CNT只能从0开始递增,并且无需初始化。

定时器周期TIM_Period:实际就是设置自定重载寄存器的值,当事件生成时更新到影子寄存器,可设置范围为0~65535。

时钟分频TIM_ClockDivision:设置定时器时钟CK_INT频率与数字滤波器采样时钟频率分频比。基本定时器没有此项功能,不用设置。

重复计数器TIM_RepetitionCounter:该项输入高级控制寄存器的专用寄存器位,利用它可以控制输出PWM的个数,基本寄存器中无需设置。

综上,虽然定时器初始化结构体由5个成员,但是对于基本定时器来说,只需要设置其中两个就可以,其余的暂时不涉及。

OK ,关于定时器的基本知识,这节就先学习这么些,下节使用基本定时器先写个小Dome来验证一下。

这篇关于032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/530040

相关文章

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

MyBatis ResultMap 的基本用法示例详解

《MyBatisResultMap的基本用法示例详解》在MyBatis中,resultMap用于定义数据库查询结果到Java对象属性的映射关系,本文给大家介绍MyBatisResultMap的基本... 目录MyBATis 中的 resultMap1. resultMap 的基本语法2. 简单的 resul

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

git stash命令基本用法详解

《gitstash命令基本用法详解》gitstash是Git中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改,这篇文章主要... 目录一、基本用法1. 保存当前修改(包括暂存区和工作区的内容)2. 查看保存了哪些 stash3. 恢

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async