无人问津也好,技不如人也罢,都应静下心来,去做该做的事。
最近在学STM32,所以也开贴记录一下主要内容,省的过目即忘。视频教程为江科大(改名江协科技),网站jiangxiekeji.com
现在开始上难度,STM32功能最强大、结构最复杂的外设——定时器,分四期介绍。
第一期介绍最基础的定时功能理论、定时器中断和定时器内外时钟源选择的代码。
第二期介绍定时器输出比较功能的代码,输出比较功能常用产生PWM波驱动电机。
本期介绍定时器输入捕获功能原理,常用测量方波频率。
最后介绍定时器的编码器接口,更方便读取正交编码器的输出波形,常用编码电机测速。
输入捕获简介
对于同一个定时器,输入捕获和输出比较,只能使用其中一个,不能同时使用,因为同一个通道的捕获/比较寄存器是公用的。
频率测量
下图是一个频率逐渐降低的方波波形,这里信号都是只有高电平的数字信号。对于STM32测频率而言,它也是只能测量数字信号的。如果你需要测量一个正弦波,那还需要搭建一个信号预处理电路,最简单的就是用运放搭一个比较器,把正弦波转换为数字信号,再输入给STM32就行了。
测量频率有两种方法:
图中的中界频率是为了减小误差,待测信号频率小于中界频率时,取测周法。
第一种是测频法(适合测高频),执行流程是,通常设闸门时间T=1s,从0开始计,每来一个上升沿,计次+1,所以在1s时间内,来了多少个周期,那它的频率就是多少Hz。
测频法代码思路:我们之前写过, 对射式红外传感器计次、 定时器外部时钟,这些代码,稍加改进, 就是测频法。比如对射式红外传感器计次,每来一个上升沿计次+1,那我们再用一个定时器,定一个1s的定时中断,在中断里,每隔1s取一下计次值,同时清计次,为下一次做准备。这样每次读取的计次值就直接是频率。对应定时器外部时钟的代码,同理。
第二种是测周法(适合测低频),我们捕获信号的两个上升沿,然后测量一下这之间持续的时间,再对时间取倒数就是频率。我们使用一个已知的标准频率fc的计次时钟。 来驱动计数器,从一个上升沿开始计,计数器从0开始,一直计到下一个上升沿,停止。计一个数的时间是1/fc,计N个数, 时间就是N/fc。N/fc就是周期, 再取个倒数, 就得到了公式 fx=fc/N。
我们本期输入捕获测频率,使用的方法是测周法
输入捕获通道
引脚进来,这里有一个三输入的异或门,这个异或门的输入接在了通道1、2、3端口。异或门的执行逻辑是当三个输入脚的任何一个有电平翻转时,输出脚就产生一次电平翻转。之后输出通过数据选择器,到达输入捕获通道1。数据选择器如果选择上面一个,那输入捕获通道的输入,就是3个引脚的异或值;如果选择下面一个,那异或门就没有用,4个通道各用各的引脚。设计这个异或门,其实还是为三相无刷电机服务的,无刷电机有3个霍尔传感器检测转子的位置,可以根据转子的位置进行换相。有了这个异或门,就可以在前三个通道接上无刷电机的霍尔传感器,然后这个定时器就作为无刷电机的接口定时器,去驱动换相电路工作,了解下就好。
然后继续看,输入信号来到了输入滤波器和边沿检测器,输入滤波器可以对信号进行滤波,避免些高频的毛刺信号误触发,然后边沿检测器,这就和外部中断那里是一样的了,可以选择高电平触发,或者低电平触发,当出现指定的电平时,边沿检测电路就会触发后续电路执行动作。另外这里,它其实是设计了两套滤波和边沿检测电路。第一套电路,经过滤波和极性选择,得到TI1FP1(TI1 Filter Polarity 1),输入给通道1的后续电路;第二套电路,经过另一个滤波和极性选择,得到TI1FP2(TI1 Filter Polarity 2),输入给下面通道2的后续电路。同理,下面TI2信号进来,也经过两套滤波和极性选择,得到TI2FP1和TI2FP2,其中TI2FP1输入给上面,TI2FP2输入给下面。在这里,两个信号进来,可以选择各走各的,也可选择进行一个交叉,让CH2引脚输入给通道1,或者CH1引脚输入给通道2,那这里为什么要进行一个交叉连接呢?这样做的目的,主要有两个。第一个目的,可以灵活切换后续捕获电路的输入,比如你一会儿想以CH1作为输入,一会儿想以CH2作为输入,这样就可以通过这个数据选择器,灵活地进行选择。第二个目的,就是可以把一个引脚的输入,同时映射到两个捕获单元,这也是PWMI模式的经典结构。第一个捕获通道,使用上升沿触发,用来捕获周期,第二个通道,使用下降沿触发,用来捕获占空比,两个通道同时对一个引脚进行捕获,就可以同时量频率和占空比,这就是PWMI模式。下面通道3和通道4也是同理。
输入信号进行滤波和极性选择后,就来到了预分频器,可以选择对前面的信号进行分频,分频后的信号就可以触发捕获电路进行工作了,每来一个触发信号,CNT的值就会向CCR转运一次,转运的同时,会发生一个捕获事件,这个事件会在状态寄存器置标志位,同时也可以产生中断。如果需要在捕获的瞬间,处理一些事情的话,就可以开启这个捕获中断,这就是整个电路的工作流程。
比如我们可以配置上升沿触发捕获,每来一个上升沿,CNT转运到CCR一次,又因为这个CNT计数器是由内部的标准时钟驱动的,所以CNT的数值,其实就可以用来记录两个上升沿之间的时间间隔,这个时间间隔,就是周期。再取个倒数,就是测周法测量的频率了。另外这里还有个细节问题,就是每次捕获之后,我们都要把CNT清0一下。这样下次上升沿再捕获的时候,取出的CNT才是两个上升沿的时间间隔。
输入捕获通道细化框图
简单理解,这个滤波器工作原理就是以采样频率对输入信号进行采样,当连续N个值都为高电平时,输出才为高电平;连续N个值都为低电平时,输出才为低电平;如果你信号出现高频钭动,导致连续采样N个值不全都一样,那输出就不会变化,这样就可达到滤波的效果。采样频率越低,采样个数N越大,滤波效果就越好
主从触发模式
其中主模式可以将定时器内部的信号,映射到TRGO脚,用于触发其他外设。
从模式呢,就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制。
触发源选择,就是选择从模式的触发信号源的,看成从模式的一部分。触发源选择,选择指定的一个信号,得到TRGI,TRGI去触发从模式,从模式可以在这个列表里,选择一项操作来自动执行
如果我们想让TI1FP1信号自动触发CNT清零,那触发源选择,就可以选中这里的TI1FP1,从模式执行的操作,就可以选择执行Reset的操作。这样TI1FP1的信号就可以自动触发从模式,从模式自动清零CNT,实现硬件全自动测量。
输入捕获基本结构
下图这个结构只使用一个通道,所以只能测量频率。在右上角这里,是时基单元,我们把时基单元配置好,启动定时器。那这个CNT,就会在预分频之后的这个时钟驱动下,不断自增,这个CNT,就是我们测周法用来计数计时的东西。经过预分频之后的时钟频率,就是驱动CNT的标准频率fc,
这里不难看出,标准频率=72M/预分频系数,然后下面输入捕获通道1的GPIO口,输入一个左上角这样的方波信号,经过滤波器和边沿检测,选择TI1FP1为上升沿触发,之后输入选择直连的通道,分频器选择不分频,当TI1FP1出现上升沿之后,CNT的当前计数值转运到CCR1里,同时触发源选择, 选中TI1FP1为触发信号,从模式选择复位操作,这样TI1FP1的上升沿,也会通过上面这一路,去触发CNT清零。当然这里会有个先后顺序,肯定得是先转运CNT的值到CCR里去,再触发从模式给CNT清零。
所以,当我们想要读取信号的频率时,只需要读取CCR1得到N,再计算fc/N,就行了;当不需要读取时,整个电路全自动的测量,不需要占用任何软件资源。
注意事项:CNT的值是有上限的,ARR一般设置为最大65535,那CNT最大也只能计65535个数,如果信号频率太低,CNT计数值可能会溢出;另外还有就是,这个从模式的触发源选择,如果想使用从模式自动清零CNT,就只能用通道1和通道2。对于通道3和通道4,就只能开启捕获中断,在中断里手动清零了,不过这样程序就会频繁中断。
PWMI基本结构
这个PWMI模式,使用了两个通道同时捕获一个引脚,可以同时测量周期和占空比。
图中的上部分结构和上面的输入捕获基本结构一样,下面多了一个通道。
首先,TI1FP1配置上升沿触发,触发捕获和清零CNT,正常的捕获周期,这时我们再来一个TI1FP2,配置为下降沿触发,通过交叉通道,去触发通道2的捕获单元。
留意左上角,最开始上升沿,CCR捕获,同时清零CNT,之后CNT++。然后,在下降沿这个时刻,触发CCR2捕获,所以这时CCR2的值,就是CNT从上升沿到下降沿的计数值即高电平期间的计数值。CCR2捕获,并不触发CNT清零,所以CNT继续++,直到下一次上升沿,CCR1捕获周期,CNT清零,这样执行后,CCR1就是一整个周期的计数值,CCR2就是高电平期间的计数值,我们用CCR2/CCR1,是不是就是占空比了
两个程序现象
第一个是输入捕获模式测频率
在这里,为了测量外部信号的频率,我们先得有个信号源,产生一个频率和占空比可调的波形。这里借用上期的代码,先用PWM模块,在PA0端口输出一个频率和占空比可调的波形。然后我们测量波形的输入口是PA6,直接用杜邦线把PA0和PA6连起来,这样就能测量自己PWM模块产生波形的频率了
第二个是PWMI模式测频率和占空比
STM32的输入捕获还设计了一个PWMI模式,即PWM输入模式,
OLED第一行显示频率,当前是1000Hz;第二行显示占空比,当前是50%