【STM32】通用定时工作原理

作者:一只大喵咪1201
专栏:《STM32学习》
格言:你只管努力,剩下的交给时间!
【STM32】通用定时工作原理_第1张图片

通用定时器

  • 通用定时器TIMx简介
  • 通用定时器功能模块组成
    • 时基单元
    • 计数模式
    • 时钟选择
    • 输入捕获
    • 输出比较
  • 总结

通用定时器TIMx简介

STM32F1 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。 STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。

使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

STM3F1 的通用 TIMx (TIM2、 TIM3、 TIM4 和 TIM5)定时器特点包括:

  • 位于低速的APB1总线上
  • 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。
  • 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
  • 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
    A.输入捕获
    B.输出比较
    C. PWM 生成(边缘或中间对齐模式)
    D.单脉冲模式输出
  • 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
  • 如下事件发生时产生中断/DMA:
    A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
    B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
    C.输入捕获
    D.输出比较
    E.支持针对定位的增量(正交)编码器和霍尔传感器电路
    F.触发输入作为外部时钟或者按周期的电流管理

通用定时器占了4个,还有4个分别是俩个高级定时器(TIM1和TIM8),俩个基本定时器(TIM5和TIM6),它们各自的功能有所区别

【STM32】通用定时工作原理_第2张图片

通用定时器功能模块组成

【STM32】通用定时工作原理_第3张图片
这是通用定时器的工作框图,下面本喵将其分为几个部分讲解。

时基单元

时基单元包括:

  • 计数器寄存器(TIMx_CNT)
  • 预分频器寄存器 (TIMx_PSC)
  • 自动装载寄存器 (TIMx_ARR)
  1. 计数器寄存器(TIMx_CNT)

它在框图中的
【STM32】通用定时工作原理_第4张图片
这个位置。

该寄存器是一个16位的寄存器

图
它的计数范围就是1~65535,超出这个范围就会发生溢出。

计数器由预分频器的时钟输出CK_CNT驱动,仅当设置了计数器TIMx_CR1寄存器中的计数器使能位(CEN)时, CK_CNT才有效。

【STM32】通用定时工作原理_第5张图片
也就是控制寄存器CR1中的位0相当于时钟CK_CNT的开关,只有它使能也就是值位1的情况下CK_CNT才会驱动CNT寄存器进行计数。

  1. 预分频器寄存器 (TIMx_PSC)

它在框图中的
【STM32】通用定时工作原理_第6张图片
这个位置。

该寄存器同样是一个16位的寄存器,

【STM32】通用定时工作原理_第7张图片
它能存放值是范围也是1~65535,它的作用就是将驱动定时器的时钟(图中的CK_PSC)进行分频,该寄存器中的值是多少,就将CK_PSC的时钟进行(PSC[15:0]+1)的分频。至于为什么是加1,是因为预分频计数器是从0开始计数的。

它是基于一个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器,这个控制寄存器带有缓冲器,它能够在工作时被改变。新的预分频器参数在下一次更新事件到来时被采用。
【STM32】通用定时工作原理_第8张图片
PSC的分频系数会在它的值的基础上加1,所以将它的值由0改为1,也就是将分频系数由1改到2。由时许图中可以清除的看到,在更新事件产生以后,CNT计数器计数的频率改变了。

预分频计数器中的值此时也从0加到1,然后再到0,如此往复循环,控制着CK_CNT的频率。

  1. 自动装载寄存器 (TIMx_ARR)

它在框图中的【STM32】通用定时工作原理_第9张图片
这个位置。

该寄存器同样是一个16位的寄存器

【STM32】通用定时工作原理_第10张图片
它能存放值是范围也是1~65535,它作用就是给计数器寄存器CNT设置一个参照,CNT中的计数值总是在和ARR中的值比较。

自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。

当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于’0’时,产生更新事件。更新事件也可以由软件产生。

【STM32】通用定时工作原理_第11张图片

在框图中可以看到,自动重装载寄存器ARR的后面是有影子的,这个影子也是一个寄存器,就叫做影子寄存器。

自动重装载器中的值是影子寄存器给它的,我们都是通过修改影子寄存器中的值,然后影子寄存器再将值给到ARR寄存器中才实现设置计数值的目的的。

将控制寄存器CR1的位7,也就是ARPE位图
使能以后,就相当于打开了影子寄存器。

影子寄存器打开和关闭的区别:

  • 打开:当我们在定时器工作的过程中修改了ARR寄存器中的值后,寄存器ARR中的值不会立马改变,而是在每次的更新事件(UEV)时,将改变后的值传送到影子寄存器,进而改变ARR中的值,也就是改变值的时候是有一个缓冲的。
    【STM32】通用定时工作原理_第12张图片
    UEV是否被允许由CR1寄存器的位1控制。
  • 关闭:当我们在定时器工作的过程中修改了ARR寄存器中的值后,会立刻将改变的值传送到影子寄存器,立刻改变ARR中的值,也就是改变值的时候是没有缓冲的

【STM32】通用定时工作原理_第13张图片
在ARPE位为0的时候,ARR中的值从0XFF改变为0X36以后,计数器CNT在计数到36以后就产生了计数器溢出,产生更新事件,发生更新中断。

【STM32】通用定时工作原理_第14张图片
在ARPE位为0的时候,ARR中的值从0XF5改变为0X36以后,计数器仍然是在计数到0XF5以后才产生计数器溢出,并没有立刻改变。在计数到0XF5后产生了更新事件后,改变后的值0X36才被传送到影子寄存器,也就是才放在了ARR中,下一次CNT计数到0X36就会产生溢出事件。

计数模式

它在框图的
【STM32】通用定时工作原理_第15张图片
这个位置。

计数模式有三种:

  • 向上计数模式
  • 向下计数模式
  • 中央对齐计数模式
  1. 向上计数模式

在向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。

每次计数器溢出时可以产生更新事件(UEV),在TIMx_EGR寄存器中(通过软件方式或者使用从模式控制器)设置UG位也同样可以产生一个更新事件。

【STM32】通用定时工作原理_第16张图片
将该位由软件置1后,并且中断是开启,就可以强制进入中断服务程序。

内部时钟分频因子不一样时,计数的频率也会不一样。

下图是当TIMx_ARR=0x36时计数器在不同时钟频率下的动作。

【STM32】通用定时工作原理_第17张图片
内部时钟分频因子是1的时候,时钟CK_CNT的频率和内部时钟CK_INT的一样。

【STM32】通用定时工作原理_第18张图片
内部时钟分频因子是2的时候,时钟CK_CNT的频率是CK_INT的一半。

  1. 向下计数模式

在向下模式中,计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动装入的值重新开始并且产生一个计数器向下溢出事件。每次计数器溢出时可以产生更新事件,TIMx_EGR寄存器中(通过软件方式或者使用从模式控制器)设置UG位,也同样可以产生一个更新事件。

只是计数的方向不一样,其他都和向上计数模式一样。

  1. 中央对齐计数模式

在中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)−1,产生一个计数器
溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。在这个模式,不能写入TIMx_CR1中的DIR方向位。它由硬件更新并指示当前的计数方向。
图
此时CR1寄存器中的位4,DIR位是不能用来设置计数方向的,只能由读取现在是处于哪个计数方向。

【STM32】通用定时工作原理_第19张图片
该模式和前俩种模式在时序图上的区别就是,CNT计数到ARR值后不变0,而是从ARR开始继续向下计数。

【STM32】通用定时工作原理_第20张图片
这是3种模式下CNT计数器寄存器中的值与时间之间的关系曲线,ARR中的值就是参照。

时钟选择

时钟源有4个:

  • 内部时钟(CK_INT)
  • 外部时钟模式1:外部输入脚(TIx)
  • 外部时钟模式2:外部触发输入(ETR)
  • 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时
    器Timer1而作为另一个定时器Timer2的预分频器。
  1. 内部时钟源

这是我们最常用的时钟源,绝大多数情况下使用的都是内部时钟源(CK_INT)。

【STM32】通用定时工作原理_第21张图片
这是它在框图中的路线。

如果禁止了从模式控制器(TIMx_SMCR寄存器的SMS=000),则CEN、 DIR(TIMx_CR1寄存器)和UG位(TIMx_EGR寄存器)是事实上的控制位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被写成’1’,预分频器的时钟就由内部时钟CK_INT提供。

SMCR位我们很少用到,本喵不再介绍,其余CEN、DIR、UG位前面都介绍过,我们直接看时序图。

【STM32】通用定时工作原理_第22张图片
内部时钟CK_INT是来源于RCC的TIMx的,然后CK_INT经过从模式寄存器处理后给CK_PSC提供时钟源,CK_PSC经过预分频寄存器PSC分频后给CK_CNT提供时钟源,所以在CEN使能以后,内部时钟进行了俩个时钟周期,CK_CNT才有了时钟信号。

其他三种模式,由于用到的比较少,在涉及到的时候本喵会详细讲解。

输入捕获

【STM32】通用定时工作原理_第23张图片
每个通用寄存器都有4个通道,这个4个通道既能输入捕获也能输出比较。

每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器),包括捕获的输入部分(数字滤波、多路复用和预分频器),和输出部分(比较器和输出控制)。

【STM32】通用定时工作原理_第24张图片
捕获过程:

  1. 选择有效输入端: TIMx_CCR1必须连接到TI1输入,所以写入TIMx_CCMR1寄存器中的CC1S=01,只要CC1S不为’00’,通道被配置为输入,并且TM1_CCR1寄存器变为只读。

【STM32】通用定时工作原理_第25张图片
通过设置CCMR1寄存器中的CC1S位来设置通道的工作模式。只要不是00,就是输入捕获模式。

  1. 根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动,我们须配置滤波器的带宽长于5个时钟周期。因此我们可以(以fDTS频率)连续采样8次,以确认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。

【STM32】通用定时工作原理_第26张图片
假设从TI1输入一个信号,我们想捕获它的上升沿,该信号我们知道它最多在5个内部时钟(CK_INT)周期内发生抖动,这些抖都可能会造成误捕获。所以通样以内部时钟(CK_INT)的频率连续采用8次,如果这8次都是高,说明我们捕获的信号是正确的,这样就可以过滤一些信号,所以也叫做滤波器。

需要将CCMR1寄存器中的
【STM32】通用定时工作原理_第27张图片
位IC1F设置成0011。

如此一来【STM32】通用定时工作原理_第28张图片滤波这一步就完成了,该信号被记作TI1F。

  1. 选择TI1通道的有效转换边沿,在TIMx_CCER寄存器中写入CC1P=0(上升沿)。

【STM32】通用定时工作原理_第29张图片
通过将CCER寄存器中的CC1P设为0,此时只有输入信号是高电平的时候才会捕获。此时边缘检测器也设置好了。

【STM32】通用定时工作原理_第30张图片

  1. 通过设置CCMR1寄存器中的CC1S位,将此时的信号IT1FP1映射再TI1上。

此时的TI1FP1不仅有一个去向,他可以映射到IC1上,也可以映射到其他通道,体现在图中的红色圈上。

【STM32】通用定时工作原理_第31张图片
这一位我们在前面讲解过。

  1. 配置输入预分频器。

通设置CCMR1寄存器中的IC1PSC1设置预分频系数

【STM32】通用定时工作原理_第32张图片
也就是可以设置被捕获信号产生了几次会产生一次捕获事件,就比如捕获高电平,通过我们前面一系列设置后的信号,产生了几次高电平后会触发一次捕获事件。

  1. 设置TIMx_CCER寄存器的CC1E=1,允许捕获计数器的值到捕获寄存器中。

【STM32】通用定时工作原理_第33张图片

当捕获使能以后,发生捕获事件时,计数器CNT中的值就会被传送到寄存器CRR1中

【STM32】通用定时工作原理_第34张图片
通过该值,我们就可以计算出捕获信号的频率等。

如果开启了中断,在发生捕获事件时就会进入捕获中断,执行中断服务函数。

输出比较

【STM32】通用定时工作原理_第35张图片
输出比较是框图中的这一部分。

此项功能是用来控制一个输出波形,或者指示一段给定的的时间已经到时。

输出比较模式的配置步骤:

  1. 选择计数器时钟(内部,外部,预分频器)

通常都是选择内部时钟(CK_INT)作为时钟源的。

  1. 将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中

ARR的值仍然是计数器CNT产生溢出事件的一个参考值,CRR是发生反转的参考值。

【STM32】通用定时工作原理_第36张图片
如上图,当计数器CNT中的值小于CRR中的参考值时,IO口输出的是低电平,当计数器CNT中的值大于CRR中的值并且小于ARR的值的时候,IO输出的是高电平。当然,具体是高电平和低电平是可以设置的。

此时
【STM32】通用定时工作原理_第37张图片
捕获/比较寄存器就设置好了。

  1. 如果要产生一个中断请求和/或一个DMA请求,设置CCxIE位和/或CCxDE位。
  2. 选择输出模式,例如当计数器CNT与CCRx匹配时翻转OCx的输出引脚, CCRx预装载未用,开启OCx输出且高电平有效,则必须设置OCxM=’01 1’、 OCxPE=’0’、 CCxP=’0’和CCxE=’1’。

【STM32】通用定时工作原理_第38张图片
模式的选择需要配置的是CCMR1寄存器中的OC1M,具体要配置什么模式,在使用的时候本喵进行详细讲解。

【STM32】通用定时工作原理_第39张图片
至此,输出控制部分就配置完了

  1. 设置TIMx_CR1寄存器的CEN位启动计数器
    此时定时器就启动了,开始了输出比较模式。

TIMx_CCRx寄存器能够在任何时候通过软件进行更新以控制输出波形,条件是未使用预装载寄
存器(OCxPE=’0’,否则TIMx_CCRx影子寄存器只能在发生下一次更新事件时被更新)。

【STM32】通用定时工作原理_第40张图片
计数器CNT中的值一旦和CCR中的值匹配,IO口的电平状态就会发生一次反转。

总结

是不是感觉很枯燥乏味?这篇文章一直都是在讲解通用定时器的原理,以及一些重要寄存器的配置。在后面本喵会介绍通用定时器具体使用的实验,这篇原理的介绍也是在为我们使用奠定一个基础。希望对大家有所帮助。

你可能感兴趣的:(STM32学习,stm32,单片机,arm)