一、简介
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
定时器最核心的部分叫做时基单元,由计数器、预分频器、自动重装寄存器构成
stm32定时器的功能十分丰富,不仅有定时中断功能,还有内外时钟源选择、输入捕获、输出比较、主从触发模式等多种功能
根据复杂度和应用场景定时器分为高级、通用、基本三个类型的定时器,我们一起来梳理一下基本定时器和通用定时器,高级定时器就不再梳理了,太复杂
二、基本定时器
基本定时器是定时器里结构最简单的,功能最少的定时器,我们先从基本定时器开始学习
基本定时器只能接内部时钟,所以上方控制器相当于通路,然后连接到psc预分频器上,这个预分频器就是用来对时钟分频的,计数器占用一份,预分频器占用x份,由于时基单元的三个器件都是16位的,所以x的取值在0 ~ 2^16-1,所以最大的分频效果为1/(2 ^16),此时计数器的分频最小,可计时的时间最长,每一个上升沿计数器就加1,在72mhz的内部时钟的频率下的计时时间最长是59s多,超过这个时间就要从0再开始计时了
自动重装寄存器的作用是存储一个阈值,当计数器达到这个值时触发中断(就是上图的ui,更新中断),清零计数器(就是上图的u,更新事件,触发内部其他电路的工作)
u更新事件通过主模式可以映射到trgo直接触发dac(数模转换器,就是实现数字信号与模拟信号的转换),过程不需要软件参与,实现了硬件的自动化,这就是主模式的作用
三、通用定时器
1、时钟源选择
- 在通用定时器中的时钟源可以有选择了,不一定非得要用内部时钟,在timx_etr引脚处接入外部时钟经过极性选择、边沿检测和预分频器以及滤波后接入触发控制器,此时这个外部时钟就可以被使用了
- 通过trgi这一路可以实现定时器级联功能,因为trgo可以连接至itr,这一路可以开启定时器的从模式,实现定时器1更新事件驱动定时器2时基单元的效果,定时器1达到阈值时定时器2加1,这样就可以实现计时时长指数级的增长
- 然后时钟还可以通过tiif_ed也就是ch1引脚,以及ti1fp1也就是ch1引脚的时钟、ti2fp2也就是ch2引脚的时钟来设定
2、时基单元
通用定时器的计数器除了向上计数还有向下计数和中央对齐计数
- 向下计数:设置一个基准值,从这个基准值开始向下减,直到计数器值为0,申请中断
- 中央对齐计数:设置一个基准值,从0开始计数到该值,申请中断,计数器不清零,然后向下减直到计数器为0,申请中断,再重复自增再自减的过程
3、输出比较和输入捕获电路
最下边这一块电路是输入捕获和输出比较电路
(1)输出比较
输出比较可以通过比较cnt(计数器)与ccr(捕获/比较)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的pwm波形
①pwm波形
pwm就是脉冲宽度调制,在具有惯性的系统中,可以对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,可以通过控制频率来做到电机控速等效果
- 频率为1/ts , 占空比为ton/ts , 分辨率为占空比的变化步距
- 占空比越高,越接近高电平,占空比越低,越接近低电平
- 占空比如果按照1%、2%、3%的步距变化,那么分辨率就是1%
- 占空比如果按照10%、20%、30%的步距变化,分辨率就是10%
②通用定时器的输出比较电路
cnt与ccr1进行比较,当cnt>=ccr1时,就会给输出模式控制器传一个信号,然后输出模式控制器就会改变它输出oc1ref的电平(然后可以将ocref映射到主模式trgo输出上去),然后遇到一个门,是一个极性选择门,cc1p寄存器写0,信号从上通道通过,也就是信号电平不翻转,cc1p寄存器写1,信号从下通道非门通过,执行逻辑取反,也就是信号电平翻转
③输出模式控制器的逻辑
该控制器是可以由寄存器oc1m[2:0]控制的
模式 | 描述 |
---|---|
冻结 | cnt=ccr时,ref保持原状态 |
匹配时置有效电平 | cnt=ccr时,ref置有效电平 |
匹配时置无效电平 | cnt=ccr时,ref置无效电平 |
匹配时电平翻转 | cnt=ccr时,ref电平翻转 |
强制为无效电平 | ref强制为无效电平 |
强制为有效电平 | ref强制为有效电平 |
pwm模式1 | 向上计数:cnt<ccr时,ref置有效电平,cnt>=ccr时,ref置无效电平 |
pwm模式2 | 向上计数:cnt<ccr时,ref置无效电平,cnt>=ccr时,ref置有效电平 |
这里的有效电平和无效电平可以被认为是高电平和低电平
其实除了pwm模式以外其他的都没啥用
④输出比较基本结构
时钟接到预分频器上,像上面提到的一样,通过运行控制寄存器来操作时基单元,然后计数器cnt不断计数并且不断与ccr进行比较,这里我们ccr的模式是比较常用的pwm1,然后输出ref波形,原理如下图所示:
- 当cnt < ccr,输出ref高电平,当cnt >= ccr时,输出ref低电平
- 可以看出pwm频率就等于计数器的更新频率
- 占空比就是ccr/(arr+1),与计数器值无关,因为计数器计数值是一个线性变化的量
- 分辨率就是占空比变化步距,与ccr和arr有关
(2)输入捕获
- 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前cnt的值被写入到ccr中,可用于测量pwm波形的频率、占空比、脉冲间隔、电平持续时间等参数
- 可配置为pwmi模式,同时测量频率和占空比
- 可配合主从触发模式,实现硬件全自动测量
①测频率的方法
- 高频信号测量频率适合用测频法:在一定时间t内,对上升沿计n次,频率为n/t,且更新慢,得到的值波动小,可以通过计数器计数以及计时器计时来达到效果
- 低频信号测量频率适合用测周法:在两个上升沿也就是一个周期内,用一频率f计n次,频率为f/n,且更新快,得到的值波动大,
- 测量频率的时候n越大,误差越小,测频法与测周法误差相等的频率为中界频率,此时两种方法计次n相同
②输入捕获电路
- 滤波器:连续多个采样,在多个采样相同时输出采样电平,不同时输出不变,起到滤波的作用
- ccer寄存器中的cc1p位选择信号极性
- ccmr1中的cc1s位对数据进行选择,icps位控制上面的分频器
- ccer中的cc1e可以控制控制信号使能或者失能
③主从触发模式
- 主从是一个形象的描述,被描述者就是stm32
- 主模式就是将内部信号映射到trgo引脚,用于触发别的外设
- 从模式就是接受一个外设产生的触发源信号,产生trgi控制自身
④输入捕获基本结构
时基单元连接到时钟上,这都是基本操作,不必多说,然后gpio输入上方波形信号,经过滤波器选择ti1fp1为上升沿(下降沿)触发,经过分频器分频,当ti1fp1出现上升沿(下降沿)之后,cnt当前计数值传到ccr1里,同时选择ti1fp1为触发源,然后开启从模式,可以设置从模式触发cnt清零
可以看到波形图在上升沿时将cnt的值给到ccr1,同时将cnt的值置为0,然后在没有再次出现上升沿的过程中cnt持续计数,再次出现上升沿时重复上述过程
⑤pwmi基本结构
- pwmi模式:使用两个通道来捕获频率和占空比
可以看到和上一个电路里的区别就是下路加了一个ti1fp2,用来捕获下降沿,出现下降沿时让cnt的值赋给ccr2,这样就记录了电平为高电平期间的计数值,且不清零cnt,占空比就可以用ccr2/ccr1得出
4、定时中断基本结构
up整理的图是非常通俗易懂的,时钟可以选择内部时钟和外部时钟(编码器就不看了),外部时钟又可以选择直接接入gpio的外部时钟etr引脚,也可以选择触发输入外部时钟,也就是ert、itrx、tix某一个,通过运行控制来操作时基单元,然后接到中断输出控制,中断输出控制用来控制中断,它对于nvic的作用就相当于nvic对于cpu的作用,起到一个筛选的作用,被允许才能接到nvic
5、预分频器时序
- ck_psc是预分频器的输入时钟
- cnt_en是计数器使能,高电平计数器正常运行,低电平计数器停止
开始时,计数器未使能,定时器时钟不运行,使能后前半段预分频器系数为1,此时定时器时钟ck_cnt与预分频器的输入时钟ck_psc相同,后半段预分频器系数为2,此时定时器时钟ck_cnt一个周期等于预分频器的输入时钟ck_psc两个周期
- 在计数器时钟的驱动下,计数器寄存器在时钟上升沿时自增,从图中可以看出自动重装器的数值为fc,因为在此之后变为0
- 在计数器寄存器由fc变为0时,产生一个更新事件
下面三行表示的是预分频器的缓冲机制:
在更改预分频控制寄存器时,预分频控制寄存器立刻变化,但是会在当前这个计数周期结束后更新到预分频缓冲器中
预分频计数器用来做分频指示,在1分频时计数器就是000000这样计数,控制相应的波形不会发生变化,在2分频时计数器就是010101这样计数,波形在0的上升沿发生变化,周期变为原来的两倍,如果3分频,那么计数器就是012012这样计数,相对应的周期就会变为原来的三倍
6、计数器时序
内部时钟分频因子就是分频系数,也就是2分频
在计数器寄存器置0的时候,计数器溢出,发生更新事件,更新中断标志置1,当更新中断标志置1时会去申请中断,中断响应后需要在中断程序中手动清零
当然,计数器、预分频器、自动重装寄存器、捕获/比较寄存器都是有缓冲机制的,效果与上小节一样,而且它们是可以手动选择是否开启的
四、rcc时钟树
先来看时钟的初始化:
st公司帮我们实现了systeminit函数,这个函数是先将内部晶振①线路接通,先以8mhz运行,然后接通外部晶振②线路,走到pllmul中,发生倍频,从外部输入的8mhz倍频为72mhz
下边有个css,时钟安全系统,负责切换时钟,一旦外部时钟失效,自动切换为内部时钟,保证系统时钟的运行,防止程序卡死
我们一般使用外部晶振,因为外部石英晶振比内部的rc震荡电路要稳定
进入到ahb中,ahb总线中有预分频器,在systeminit里配置的分配系数为1,所以ahb中的时钟为72mhz,进入apb1总线,apb1的预分频器在systeminit里配置的分频系数为2,所以apb1的时钟为36mhz,它连接的普通外设的时钟为36mhz,而因为apb1的预分频系数不为1,所以连接定时器2~7的频率要 * 2,也就是连接定时器2 ~ 7的时钟为72mhz
apb2在systeminit里配置的分配系数为1,所以apb2连接所有外设的时钟都是72mhz
除此以外我们可以看到每一个线路连接外设之前都会和外设时钟使能经过一个与门,这个外设时钟使能就是rcc_apb2/1periphclockcmd作用的地方,打开时钟就是在这个位置写1,可以让时钟通过与门输出给外设
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论