30.3. 基本定时器功能框图¶
基本定时器的功能框图包含了基本定时器最核心内容,掌握了功能框图,对基本定时器就有一个整体的把握,在编程时思路就非常清晰,见图
31‑1。
首先先看图
31‑1中绿色框内容,第一个是带有阴影的方框,方框内容一般是一个寄存器名称,比如图中主体部分的自动重载寄存器(TIMx_ARR)或PSC预分频器(TIMx_PSC),这里要特别突出的是阴影这个标志的作用,它表示这个寄存器还自带有影子寄存器,在硬件结构上实际是有两个寄存器,源寄存器是我们可以进行读写操作,而影子寄存器我们是完全无法操作的,有内部硬件使用。影子寄存器是在程序运行时真正起到作用的,源寄存器只是给我们读写用的,只有在特定时候(特定事件发生时)才把源寄存器的值拷贝给它的影子寄存器。多个影子寄存器一起使用可以到达同步更新多个寄存器内容的目的。
接下来是一个指向右下角的图标,它表示一个事件,而一个指向右上角的图标表示中断和DMA输出。这个我们把它放在图中主体更好理解。图中的自动重载寄存器有影子寄存器,它左边有一个带有“U”字母的事件图标,表示在更新事件生成时就把自动重载寄存器内容拷贝到影子寄存器内,这个与上面分析是一致。寄存器右边的事件图标、中断和DMA输出图标表示在自动重载寄存器值与计数器寄存器值相等时生成事件、中断和DMA输出。
图 31‑1 基本定时器功能框图
30.3.1. ①时钟源¶
定时器要实现计数必须有个时钟源,基本定时器时钟只能来自内部时钟,高级控制定时器和通用定时器还可以选择外部时钟源或者直接来自其他定时器等待模式。我们可以通过RCC专用时钟配置寄存器(RCC_DCKCFGR)的TIMPRE位设置所有定时器的时钟频率,我们一般设置该位为默认值0,即TIMxCLK为总线时钟的两倍,使得表
31‑1中可选的最大定时器时钟为84MHz,即基本定时器的内部时钟(CK_INT)频率为84MHz。
基本定时器只能使用内部时钟,当TIM6和TIM7控制寄存器1(TIMx_CR1)的CEN位置1时,启动基本定时器,并且预分频器的时钟来源就是CK_INT。对于高级控制定时器和通用定时器的时钟源可以来找控制器外部时钟、其他定时器等等模式,较为复杂,我们在相关章节会详细介绍。
30.3.2. ②控制器¶
定时器控制器控制实现定时器功能,控制定时器复位、使能、计数是其基础功能,基本定时器还专门用于DAC转换触发。
30.3.3. ③计数器¶
基本定时器计数过程主要涉及到三个寄存器内容,分别是计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR),这三个寄存器都是16位有效数字,即可设置值为0至65535。
首先我们来看图
31‑1中预分频器PSC,它有一个输入时钟CK_PSC和一个输出时钟CK_CNT。输入时钟CK_PSC来源于控制器部分,基本定时器只有内部时钟源所以CK_PSC实际等于CK_INT,即84MHz。在不同应用场所,经常需要不同的定时频率,通过设置预分频器PSC的值可以非常方便得到不同的CK_CNT,实际计算为:fCK_CNT等于fCK_PSC/(PSC[15:0]+1)。
图
31‑2是将预分频器PSC的值从1改为4时计数器时钟变化过程。原来是1分频,CK_PSC和CK_CNT频率相同。向TIMx_PSC寄存器写入新值时,并不会马上更新CK_CNT输出频率,而是等到更新事件发生时,把TIMx_PSC寄存器值更新到影子寄存器中,使其真正产生效果。更新为4分频后,在CK_PSC连续出现4个脉冲后CK_CNT才产生一个脉冲。
图 31‑2 基本定时器时钟源分频
在定时器使能(CEN置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有影子寄存器,可以通过TIMx_CR1寄存器的ARPE位控制影子寄存器功能,如果ARPE位置1,影子寄存器有效,只有在事件更新时才把TIMx_ARR值赋给影子寄存器。如果ARPE位为0,修改TIMx_ARR值马上有效。
30.3.4. 定时器周期计算¶
经过上面分析,我们知道定时事件生成时间主要由TIMx_PSC和TIMx_ARR两个寄存器值决定,这个也就是定时器的周期。比如我们需要一个1s周期的定时器,具体这两个寄存器值该如何设置内。假设,我们先设置TIMx_ARR寄存器值为9999,即当TIMx_CNT从0开始计算,刚好等于9999时生成事件,总共计数10000次,那么如果此时时钟源周期为100us即可得到刚好1s的定时周期。
接下来问题就是设置TIMx_PSC寄存器值使得CK_CNT输出为100us周期(10000Hz)的时钟。预分频器的输入时钟CK_PSC为84MHz,所以设置预分频器值为(8400-1)即可满足。