STM32定时器是 ST MCU 内部最基础且常用的外设,实际应用尤为普遍。去年,电堂推出了《STM32 TIMER基础及常规应用介绍》,为大家梳理了 STM32 TIMER 的庞大内容,涵盖 TIMER 的基本应用原理、常规应用等。现在将课程内容整理为文章,针对STM32定时器有基本了解的用户,分享具体的应用实现环节及常见问题解决。
STM32定时器除了基本计数定时功能外,还对外拓展了输入、输出通道,从而实现输入捕捉、比较输出功能。
输入捕获【Input Capture】基本原理:
定时器针对外部输入信号或内部触发信号实行边沿捕捉;产生捕捉事件,并可以触发中断或DMA请求,同时记录捕捉时刻计数器的值。基于这个原理,配合计数器实时计数功能可以对捕捉信号进行脉冲宽度的测量,进而实现对周期性波形测量其周期或占空比,或者用来做通信解码。
具体到STM32定时器,输入捕获的功能主要靠捕捉比较单元来实现。输入捕获模式下:当捕获单元捕捉到外来有效信号边沿事件时【上升沿或下降沿】,将此刻计数器的值锁存到CCR影子寄存器并自动将CCR影子寄存器的值拷贝进CCR预装载寄存器,以供用户读取。
关于CCR寄存器,前面多次提到过。它也是由影子寄存器和预装寄存器组成,带预装使能控制位。在输入模式下,此时CCR对用户是只读的,不可对其进行修改、赋值。
什么信号可以作为捕捉信号?
两类信号可作为捕捉信号:
1. 来自定时器的各个输入通道的输入信号,比如TI1/TI2/TI3/TI4这些输入信号;
2. 内部触发输入信号,比如ITR0,ITR1,ITR3等,它们映射到各个输入捕捉通道;前面提到过ITR信号往往来自其它定时器的触发输出。
外部输入信号作为输入捕获信号,往往要经过如下几个阶段:一般经过滤波、边沿检测、极性选择、捕捉信号选择、捕捉信号分频,最终进入捕捉功能模块从而完成输入捕捉。其中边沿检测、极性选择确定捕获单元对捕获信号的捕捉极性,即捕捉上升沿还是下降沿,甚至双沿捕捉。
捕捉信号选择是指对可能作为输入捕获信号的信号进行选择,前面提到过了可能作为捕获信号的信号源有两大类;捕捉信号分频是指对将被用作捕获信号的信号进行分频,比如2分频、3分频等,分频之后送到捕捉功能模块去完成输入捕捉。
输入信号的滤波
1、外部引脚输入信号的滤波
为了防止因为输入信号上的噪声或边沿抖动而导致误计数、误触发,我们可以针对外部输入信号进行合适的滤波。
用户要做的就是针对输入信号具体情况【频率、噪声等】,通过寄存器配置适当的滤波参数,选择适当采样时钟和采样次数,其它事情交给定时器硬件去处理。这样也可以减少因为做滤波而导致的软件开销。
假设我们让定时器对某输入通道的信号进行捕捉,捕捉极性为上升沿。设置滤波的采样时钟与定时器内部时钟频率一致,采样次数为4次。则每当捕捉到上升沿时,硬件连续根据采样频率来采样4次【包括发生捕捉触发沿的那一次】。如果4次采样结果均为高电平,则此次触发有效。并可以产生触发事件,该事件可以触发中断或DMA请求,同时捕捉单元将此刻计数器的值放入到捕捉比较寄存器CCR中。
当然,如果捕捉到触发边沿后,没法做到连续4次采样均为高电平,则该触发无效,将会被丢弃。这样达到滤除噪声的目的。
2、内部触发输入信号ITRx作为输入捕捉信号
与输入捕获相关的事件
1. 捕获时刻的计数器值的锁存到对应捕获通道的CCRx寄存器;
2. 对应通道的捕获事件/中断标志会被置位;【CCxIF@TIMx_SR】;
3. 如果允许了 捕捉中断或DMA请求,可以触发中断或DMA请求,其它取决于CCxIE/CCxDE @TIMx_DIER的配置;
4. 如果发生连续的捕获事件,前次CCxIF没有清零的话会置位CCxOF@TIMx_SR;
5. 对于CCxIF标志可以软件清零或读取CCR来清零;
6. 可以通过置位CCxG@TIMx_EGR来软件触发输入捕获事件。
与输入捕获相关的事件主要就这些,我们要做到心中有数。只要了解它们后,在我们的定时器的实际应用中才能灵活使用它们,实现我们需要的功能。如在发生输入捕获事件时,利用相关中断或DMA请求实现其它功能,比如做数据的更新、ADC的启动、其它定时器的启动等等。
3、通过输入捕获测量脉冲周期
在输入捕捉模式下,定时器可用于测量外部信号周期。根据定时器时钟、预分频器和定时器分辨率,可推导出最大测量周期。
相应的定时器配置包括:
1. 通过对CCMRx 寄存器中的 CCxS 位选择有效输入。
2. 根据需要,通过对 CCMRx 寄存器中的 IC1F[3:0] 位执行操作以编程滤波器参数,并通过对IC1PSC[1:0] 位执行写操作以编程预分频器。
3. 通过对 CCxNP/CCxP 位执行写操作选择极性,即选择上升沿触发、下降沿触发或边沿触发。
当输入通道检测到相应的信号发生跳变时,可使用输入捕捉模块进行捕捉。要获取外部信号周期,需连续进行两次捕捉,通过将两次捕捉到的值相减可计算得到周期。
对于单沿捕捉,计数器采用向上计数模式,待测信号不长于计数器的计数周期时:
假设两次连续捕捉值为 CCRx_tn 和 CCRx_tn+1
如果 CCRx_tn < CCRx_tn+1:捕捉宽度= CCRx_tn+1 - CCRx_tn
如果 CCRx_tn > CCRx_tn+1:捕捉宽度= (ARR_max - CCRx_tn) + CCRx_tn+1
如果待测信号周期长于当前计数器周期的话,需要考虑溢出问题。实际应用中有时因为忽略了这点而导致测试不正确。
一种较特殊的测量脉宽及占空比的模式:
PWM输入模式
首先说说PWM输入模式工作原理:它是基于输入捕获与定时器从模式相结合的一个具体应用;同一个外部输入引脚【仅限于TI1/TI2的】的输入滤波信号【TIxFPx】映射到2个捕捉通道【仅限于IC1/IC2】,且配置为相反的捕捉极性,即一个通道捕捉上沿,另一个通道捕捉下沿。
定时器配置在复位从模式,外部输入的滤波信号TIxFPx作为定时器的触发信号。
经过两次连续的捕捉即可方便地测得信号的周期及占空比。【前提:待测信号周期不长于当前定时器计数周期】
需要强调提醒的是:
PWM输入模式测量脉宽和占空比,该方法只适用于来自定时器通道1或通道2的TI1或TI2输入信号,而且输入捕捉通道1【 IC1 】与捕捉通道2【IC2 】配合使用。一路直接输入,一路间接输入。一路捕捉上升沿,一路捕捉下降沿。同时,输入信号经滤波和极性选择后提供触发信号给从模式控制器,让定时器工作在复位从模式。
只有来自TI1或TI2的外来信号才能产生触发信号连接到从模式控制器。
现有ST参考库代码也有最大时长问题。即待测信号周期超过ARR所对应的时间后,得考虑溢出事件的统计问题,须自行修改代码。
通过PWM输入模式测量脉宽和占空比,它有其测试方面的方便性。只需两次捕捉,无需过多运算即可得出脉冲的宽度与占空比。但也有其局限性,通道不能随意,还必须结合定时器的复位从模式。
如果我们不使用PWM输入模式测量脉冲宽度和占空比,往往就没有通道选择上的限制,可以一个通道也可以两个通道,自由度更大,也无须一定工作在从模式。但软件代码实现方面稍嫌麻烦点。
1、外部输入信号的直接输入与间接输入
该说法只存在于输入通道1与通道2之间或者通道3与通道4之间。
所谓直接输入,即各类输入信号经过滤波、极性选择或者分频之后连接到各自对应的输入捕获通道,这时就是直接输入。
如:TI1FP2就是通道2的间接输入信号,TI3FP4就是通道4的间接输入信号。换言之,通道1的输入捕捉信号并非一定来自TI1,而可能来自TI2的信号。请弄清这些细节,不然有些地方看不懂或不知配置。
2、关于输入捕获测量异常的提醒
实际应用过程中使用TIMER进行输入捕获测量时间失败者较常见,常见的原因可能有如下几方面:
1. 待测量的脉冲长于当前ARR所对应的时间,代码又没考虑溢出事件;
2. 使用PMW输入模式测量时选择了TI1/TI2以外的通道;
3. CCR寄存器整体上是可读可写的。但是,当相应通道配置为捕获输入时,CCR为只读寄存器,即用户不可修改或赋值。
4. 在发生捕获事件时,CCR影子寄存器的内容由硬件自动将其拷贝到CCR预装寄存器,以供用户或DMA读取。