在STM32F407中,有2个基本定时器,TIM6 和 TIM7。
不同的芯片型号,定时器的个数不一样,不一定有基本定时器。
基本定时器用作:延时、定时中断、驱动DAC转换。
凡是需要周期性工作的外设(如计数器)都需要相应的工作时钟信号,以便人们知道或更改它的工作周期(如改变计数频率)。
1. 时钟源选择:内部时钟源(CK_INT):Clock Internal
![](https://i-blog.csdnimg.cn/blog_migrate/3fef12bfd4c771da5f0675cc1be6d3fa.png)
● 解读如下:
1. 内部时钟源CK_INT是由APB1经2分频得到,所以有:
基本定时器的工作时钟TIMxCLK = CK_INT = 84MHz。
2. 根据下面框图:CK_PSC = CK_INT,即基本定时器工作时钟与预分频器工作时钟相同。但注意:基本定时器的工作时钟TIMxCLK 不等于 基本定时器的计数器的工作时钟CK_CNT,TIMxCLK经PSC分频后才向计数器提供CK_CNT。
换句话说,TIMxCLK是整个基本定时器的工作时钟;CK_CNT是其中计数器CNT的实际工作时钟。
![](https://i-blog.csdnimg.cn/blog_migrate/4110d395c92148ee9a7537260bbfeb47.png)
CNT_INIT:猜测是 counter internal interrupt ----定时器内部中断
2. 基本定时器框图:
注意:框图中自动重载寄存器(ARR)和预分频器(PSC)底部有一片阴影,表示存在影子寄存器
![](https://i-blog.csdnimg.cn/blog_migrate/082a01842da41dbbec58acbdc15b8651.png)
U:猜测是 update 更新 ---- U +
![](https://i-blog.csdnimg.cn/blog_migrate/c7bf77d276814d32b0fb2980399cda55.png)
表示更新事件UEV
UI:猜测是update interrupt 更新中断
注意框图下面的标注,阴影标志描述中的“预装载寄存器”可联系下文双寄存器机制理解。自动重载寄存器指向CNT COUNTER 表示:产生UEV(未搞懂)时,自动重载寄存器可以让基本定时器的计数器停止、清零或递增:停止情况未知;计数到重载值时自动清零;未计到重载值就继续递增。
产生UEV ----> 更新影子寄存器的值 ----> 产生更新中断 / DMA
UG与UEV的关系:软件将UG置1是人工产生一次UEV事件的方法,常用于确保两个影子寄存器的值在首次计数前就得到更新。
U+箭头指向自动重载寄存器 这是什么意思?U+箭头这个更新事件是什么?
依据时钟树易知:2个基本定时器TIM6和TIM7都挂靠在APB1。所以定时器时钟:84MHz。
![](https://i-blog.csdnimg.cn/blog_migrate/3b0c782ae650e1f1b1bf6c1b7026613d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/133c12cff47f143f66294d6625a5c248.png)
3. 功能特性
3.1. 时基单元
时基:时间基准
![](https://i-blog.csdnimg.cn/blog_migrate/b3ecdd3d32046febf9c995df12ce1fa3.png)
● 解读如下:
1. 自动重载寄存器(TIMx_ARR) = 自动重载预装载寄存器 + 自动重载影子寄存器。
对自动重载寄存器进行读/写操作时,实际上操作的对象只是自动重载预装载寄存器,而真正完成重载工作的是自动重载影子寄存器。
同理:预分频器(TIMx_PSC) = 预分频器控制寄存器 + 预分频器缓冲区 + 预分频器计数器。
对预分频器进行读/写操作时,实际上操作的对象只是预分频器控制寄存器,而真正完成分频工作的是预分频器缓冲区。(现在怀疑真正完成分频的应该是预分频器影子寄存器,而猜测关于缓冲区的时序图应该是错误的,应该把缓冲区改为影子寄存器,缓冲区应该只是指控制寄存器与影子寄存器直接的缓冲区域,应该与控制寄存器同步更新内容值)
预分频器计数器也是16位递增,工作时钟信号便是CK_PSC(详见下文)。
总体:基本定时器TIMx = 基本定时器的计数器(TIMx_CNT) + 自动重载寄存器(TIMx_ARR)。
根据网络资料补充:
自动重载寄存器TIMx_ARR和预分频寄存器TIMx_PSC都具有预装载功能,即每类寄存器具有双寄存器机制,分别由各自的影子寄存器和预装载寄存器组成。影子寄存器是真正起作用的寄存器,预装载寄存器为影子寄存器提供缓冲,用户只能操作预装载寄存器。
ARR的预装载功能可由软件开启或关闭。关闭预装载功能时,写入预装载寄存器的内容将立即传入影子寄存器,使修改的内容生效。开启预装载功能时,写入预装载寄存器的内容将在更新事件(计数器溢出)发生时,才传入影子寄存器并生效。
2. UEV:update event 更新事件(详见寄存器,下同)
3. APRE:auto_reload preload enable 自动重载预装载使能 (ARR的缓冲 / 影子寄存器 选择位,注意:我认为系统默认PSC是启用缓冲的,且无法由用户修改,用户只能决定ARR是否也缓冲)
4. UDIS:update disable 更新禁止 (决定是否允许生成更新事件UEV)
● 更新 (UEV) 事件可通过以下三种事件之一生成: (UDIS为0时)
— 计数器上溢/下溢
— 将 UG 位置 1
— 通过从模式控制器生成的更新事件
![](https://i-blog.csdnimg.cn/blog_migrate/9398c8a21d5750c1914035da98ed1a31.png)
● 解读如下:
1. 这里的计数器是指“基本定时器的计数器”。
2. CK_PSC:prescaler clock 预分频器工作时钟 ----预分频器计数器的工作时钟
根据结论:凡是需要周期性工作的外设(如预分频器计数器)都需要相应的工作时钟信号,以便人们知道并更改它的工作周期(如改变计数频率)。
因此对于整个预分频器来说,CK_PSC是等待处理的输入信号;而仅对于预分频器计数器来说,CK_PSC是为自己正常运转所提供的工作时钟。
整个预分频器的工作: CK_PSC(输入)----> 预分频器 ----> CK_CNT(输出)
CK_PSC本质上是:挂靠的APBx经2分频后的定时器时钟信号。
3. CK_CNT:counter clock 计数器工作时钟 ----基本定时器的计数器的工作时钟
注意:基本定时器的工作时钟TIMxCLK 不等于 基本定时器的计数器的工作时钟CK_CNT。
CK_CNT本质上是:CK_PSC经TIMx_PSC处理(分频)后得到的时钟信号。
整个预分频器的工作: CK_PSC(输入)----> 预分频器 ----> CK_CNT(输出)
4. CK_CNT的作用:作为基本定时器的计数器的工作时钟。 ----即对CK_PSC分频的原因
5. CEN:counter enable 计数器使能控制位 ----无下划线"_"即为寄存器的控制位 / 标志位
CNT_EN:counter enable 计数器使能信号 ----有下划线"_"即为实际电平信号
理解为:基本定时器的计数器在实际工作中,使能控制位被置1后,使能信号还需要等到下一个时钟周期才置1(有效电平)。只有CNT_EN置1时,计数器才会真正开始工作。
![](https://i-blog.csdnimg.cn/blog_migrate/7d15eeb4bec46f6569ade7a3d088df18.png)
解读如下:
1. “该预分频器基于TIMx_PSC 寄存器中的 16 位寄存器所控制的 16 位计数器。” 等价于:
预分频器(TIMx_PSC) = 预分频器控制寄存器 + 预分频器缓冲区 + 预分频器计数器。
2. “预分频器可对计数器时钟进行分频”这里的“计数器”是指预分频器计数器,因此被分频处理的是预分频器计数器的输入时钟(同时也是工作时钟)。
3. “由于 TIMx_PSC 控制寄存器有缓冲,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。 ”
理解为:在实际工作中,若需要在运行过程中实时更改预分频比,应该考虑前提条件“保证周期完整性”。因此系统默认预分频器使能缓冲且用户无法修改,所以在该条件下,更改预分频器控制寄存器的值后,当下一更新事件发生时预分频器缓冲区才会更改为新分频比。
影子寄存器
PSC(预分频器)和ARR(自动重载)都有影子寄存器。
分频和重载值产生实际效果的步骤:
![](https://i-blog.csdnimg.cn/blog_migrate/3e236e2d8317e72804ed020853faeef3.png)
APRE位:(别人的理解)决定ARR是否启用影子寄存器。
(手册的理解)ARR恒使用影子寄存器,但能决定是否缓冲,即寄存器本体的内容传送到影子寄存器(此过程称为“同步数据”)的时刻(寄存器本体的内容一旦发生改变就立即传送or等到发生更新事件时才会传送)。
附上网络资料:
![](https://i-blog.csdnimg.cn/blog_migrate/fcbd1fba749ece62555171b133d69ed0.png)
下面是别人的理解:(非重点)
启用影子寄存器后的机制:
软件操作的是寄存器本体,但实际上能够真正作用的是影子寄存器。
当产生更新事件的时候,寄存器本体会把自己里面的数值加载到影子寄存器中,由影子寄存器起作用。
影子寄存器的作用:
当计数正在进行(没有产生更新事件的时候),人为去改寄存器的值是没有作用的(新重载值不起效),因为新重载值没有更新到影子寄存器中,这种机制用于保护完整周期。
思考:由于启用影子寄存器后,只有在产生一次溢出事件才会将预分频寄存器的值更新到影子寄存器,那如何在第一次计数就能使新重载值起作用?
解决方法:软件更新:对更新事件寄存器的UG位置1,人为产生一次更新事件,就会更新所有寄存器(准确来说只是初始化基本定时器的计数器和预分频器计数器),这种方法与正常溢出的效果相同,从而将寄存器中的值更新到对应的影子寄存器,影子寄存器就能在第一次计数起作用了。
上述内容理解后,下面的示例应该不难理解:
预分频比实时发生变化时,一些计数器行为的示例:(当TIMx_ARR=0xfc时改变预分频数)
![](https://i-blog.csdnimg.cn/blog_migrate/26e6191f84160f5fc7228749f73b444a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1a810e38964ede3334f927861eb5b958.png)
3.2. 计数模式
![](https://i-blog.csdnimg.cn/blog_migrate/0a166a0ce08f4b30b85e47ee523a5841.png)
● 解读如下:
1. 由于基本定时器的计数器是递增的,所以计数器工作是从0计数到自动重载值(向上计数),且计数到重载值时生成计数器上溢事件后自动清零。
2. “直到 UDIS 位中写入 0 前便不会生成任何更新事件,但计数器和预分频器计数器都会重新从 0 开始计数(而预分频比保持不变) ”我猜测这句话表述有误,结合UDIS位的描述应该是:
----“直到UDIS位写入 0 前虽然不会生成更新事件,但如果将UG位置 1,或者从 从模式控制器接收到硬件复位,则会重新初始化计数器和预分频器,即计数器和预分频器计数器都会重新从 0 开始计数(而预分频比保持不变,即预分频器控制寄存器的值不变)”。
![](https://i-blog.csdnimg.cn/blog_migrate/7649a1337ff2be2ec656300a010fe403.png)
● 解读:更新所有寄存器 ---- 重点主要是更新2个影子寄存器罢了。
简单示例:当TIMx_ARR = 0x36时:
![](https://i-blog.csdnimg.cn/blog_migrate/04e263a83663c72917995c1a7ce2f3b1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/15929c417a0fbbe15c72de0d421401e3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3371b760be7ba6cea87ee67adad5e3fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b90c82d09ae37a1a61277448abe55750.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9e0610f3e5ed5b50b395d3a836de29a9.png)
感觉有矛盾,我认为 “预装载” = “缓冲”,既然APRE=1了,不是应该为(TIMx_ARR已预装载)了吗?
4. 寄存器
4.1. TIMx_CR1:control register 控制寄存器 1
![](https://i-blog.csdnimg.cn/blog_migrate/2b81329fbcf346a4f7adb4d5011842d2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a222e4ebfa111246bcddb75058c982b2.png)
称之为“ARR缓冲使能”更合理。
"当ARPE位为0时,自动重载寄存器(TIMx_ARR)不进行缓冲",即TIMx_ARR及其影子寄存器是连通的(两者之间无缓存),同步更新数据。
"当ARPE为1时,自动重载寄存器(TIMx_ARR)进行缓冲",即TIMx_ARR及其影子寄存器两者之间存在缓存机制,只有在每次产生更新事件(UEV)时,TIMx_ARR的值才会被传到影子寄存器中起作用。
● 更新 (UEV) 事件可通过以下三种事件之一生成: (UDIS为0时)
— 计数器上溢/下溢
— 将 UG 位置 1
— 通过从模式控制器生成的更新事件
生成更新事件EUV后,将会更新影子寄存器的值。 ----EUV的作用
![](https://i-blog.csdnimg.cn/blog_migrate/5b1e29f11d631c823df0996deca05b63.png)
计数器指基本定时器的计数器。一般人称之为:0 --- 连续模式 , 1 --- 单次模式 。
![](https://i-blog.csdnimg.cn/blog_migrate/96501703add571a9bd797ed57db33fd0.png)
URS为0时,3类事件中任一发生都会生成更新中断;
URS为1时,只有发生计数器上溢事件时才会生成更新中断。
![](https://i-blog.csdnimg.cn/blog_migrate/56a465318bfbb1b01d59d753de25cd84.png)
“初始化计数器和预分频器”,即计数器和预分频器计数器都会重新从 0 开始计数(而预分频比保持不变,即预分频器控制寄存器的值不变)。
![](https://i-blog.csdnimg.cn/blog_migrate/9f3bb020714995d7c5bc245474014077.png)
4.2. TIMx_DIER:DMA/Interrupt enable register DMA/中断使能寄存器
![](https://i-blog.csdnimg.cn/blog_migrate/4a5ca54002fa5011b0862ddf82fa94a9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/133be22bd94891c745a915715d721045.png)
4.3. TIMx_SR:status register 状态寄存器(注意不是用于初始化,而是用于中断程序中判断发生的紧急事件类型)
![](https://i-blog.csdnimg.cn/blog_migrate/851f8a3002d71b512e8fff1b07af68c2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8b642417e34c8be0f4af9b394b617ff8.png)
UIF:update interrupt flag 更新中断标志位。
发生更新事件UEV时,硬件会自动将UIF位置1,但后续需要软件清零。
UDIS:update disable 更新禁止
URS:update request source 更新请求源
— 上溢或下溢并且当 TIMx_CR1 寄存器中 UDIS = 0 时,解读为:
因为无论URS为0还是1,UEV都包含计数器上溢事件,只需要满足UDIS为0即可产生中断。
— 当由于 TIMx_CR1 寄存器中 URS = 0 且 UDIS = 0 而通过软件使用 TIMx_EGR 寄存器中
的 UG 位重新初始化 CNT 时,解读为:
当URS=0时,UEV包含UG位置1事件,而UG位的作用就是初始化基本定时器的计数器和预分频器计数器。
4.4. TIMx_EGR:event generation register 事件生成寄存器(在ARR缓冲时人为产生一次更新事件,以初始化计数器)
![](https://i-blog.csdnimg.cn/blog_migrate/32343802dc75e624dc4e178038e765d3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c67b0113d779ec2a150ecd39ba36f40e.png)
UG:update generation 更新生成 ----用来初始化基本定时器的计数器和预分频器计数器
4.5. TIMx_CNT:counter 计数器
![](https://i-blog.csdnimg.cn/blog_migrate/020ca96590b30a174c10c21a400c4dcf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/06d58f5951ce81855f1b18386b4f6f6b.png)
存放基本定时器的计数器当前的计数值。
4.6. TIMx_PSC:prescaler 预分频器
![](https://i-blog.csdnimg.cn/blog_migrate/ea5b43838dcfcd330795f5f465e8f114.png)
![](https://i-blog.csdnimg.cn/blog_migrate/730cef298d53dd19563db1794d98ab33.png)
对预分频器进行读/写操作时,实际上操作的对象只是预分频器控制寄存器,而真正完成分频工作的是预分频器影子寄存器。
4.7. TIMx_ARR:auto-reload register 自动重载寄存器
![](https://i-blog.csdnimg.cn/blog_migrate/ef1772b5be9d331075ab76273074e4a3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7abbfcdb986c7ee4c2f8dd73b7fce39b.png)
对自动重载寄存器进行读/写操作时,实际上操作的对象只是自动重载预装载寄存器,而真正完成重载工作的是自动重载影子寄存器。
[总结]
基本定时器( 16位,递增计数 ----> 从0开始,计数到重载值时触发计数中断 )
① 计数方向:递增 计数范围 0到
![](https://i-blog.csdnimg.cn/blog_migrate/4211d45889cdef2a6dc1d7b148e5b03c.png)
② 作用:延时,定时中断,开启DAC转换(驱动DAC)。
③ 延时:周期计算:已知定时器时钟都是84MHz,需知预分频数,从而算出每计1个数的周期。
④ 数量:2个,分别是TIM6和TIM7
预分频器跟基本定时器的计数器都是16位。