定时器的输入捕获
最终程序现象:
1.输入捕获模式测频率
2.PWMI模式(PWM输入模式)测频率和占空比
输入捕获电路:左边这一部分。 右边的就是输出比较部分。
4个输入捕获和输出比较通道,共用4个CCR寄存器,另外它们的CH1到CH4,4个通道的引脚,也是共用的。所以对于同一个定时器来说,输入捕获和输出比较,只能使用其中一个,不能同时使用。
TIMx_CH1-4是边沿信号输入引脚,一旦有边沿,比如上升沿,那这一块输入滤波和边沿检测电路就会检测到这个上升沿,让输入捕获电路产生动作。都是检测电平跳变,然后执行动作。只不过外部中断执行的动作是向CPU申请中断。而这里电路执行的动作就是控制后续电路,让当前CNT的值,锁存到CCR寄存器中。对比输出比较,引脚是输出端口;输入捕获,引脚是输入端口。输出比较是根据CNT和CCR的大小关系来执行输出动作。输入捕获是接收到输入信号,执行CNT锁存到CCR的动作。这就是输入捕获的执行流程和与输出比较的区别。那设计这样一个输入捕获电路有什么用呢?
脉冲间隔和频率意思差不多,电平持续时间和占空比差不多。 这些参数通过输入捕获电路,都可以很方便地进行测量。 如何配置输入捕获电路来测量这些参数,就是此节的任务。
高级定时器的输入捕获弟阿鲁和通用定时器没有区别,都是一样的。基本定时器没有输入捕获功能。
PWMI和主从触发模式,设计的非常巧妙,把这两个功能结合起来,测量频率占空比就是硬件全自动执行。软件不需要任何干预,也不需要进中断。需要测量的时候,直接读取CCR寄存器的值就可以了,使用非常方便,而且极大地减轻了软件的压力。
这里信号都只有高低电平的数字信号,对于STM32测频率而言,它也只是测量数字信号的,如果需要测量一个正弦波,那还需要搭建一个信号预处理电路,最简单的就是用运放搭一个比较器,把正弦波转换为数字信号,再输入给STM32就行了。那还要考虑一下隔离的问题,比如用一些隔离放大器、电压互感器等元件,隔离高压端和低压端,保证电路的安全,总之经过处理最终输入给STM32的信号。就是这样的数字信号,高电平3.3V,低电平0V
测频法符合频率的定义。适合测量高频信号,在闸门时间内,最好要多出现一些上升沿,计次数量多一些,这样有助于减小误差。假如定了1s的闸门时间,结果信号频率非常低,1s的时间只有寥寥无几的几个上升沿,甚至1个上升沿都没有,那总不能认为频率为0,再计次N很少时,误差会非常大,
测周法实际上并没有一个精度无穷大的秒表来测量时间,测量时间的方法,实际上也是定时器计次。使用一个已知的标准频率fc的计次时钟,来驱动计数器。从一个上升沿开始一直到下一个上升沿停止。适合测量低频信号。低频信号周期比较长,计次就会比较多,有助于减小误差,否则的话,比如标准频率fc为1MHz,待测信号频率太高,比如待测信号500KHz,那在一个周期内只能计一两个数,如果待测信号再高一些,甚至一个数也计不到,总不能认为频率无穷大。所以测周法需要的待测信号频率低一些。
然后测频法测量结果更新的慢一些,数值相对稳定,测周法更新的快,数据跳变也非常快。所以它自带一个均值滤波,如果在闸门时间内波形频率有变化,那得到的其实是一段时间的平均频率,如果闸门时间选为1s,那么每隔1s才能得到1次结果。
反观测周法,它只测量一个周期就能出一次结果,所以出结果额速度取决于待测信号的频率,一般而言,待测信号都是几百几千Hz,所以一般情况下,测周法结果更新更快,但由于只测量一个周期,所以结果值会受噪声的影响,波动比较大,这就是两种方法的基本特征对比。
那么多高算高,多低算低,这就涉及到中界频率的概念了,中界频率就是测频法与测周法误差相等的频率点。
测频法计次和测周法计次,计次数量N,尽量要大一些,N越大,相对误差越小,因为在这些方法中,计次可能会存在正负1误差,比如测频法,在闸门时间内,比如在最后的时间里,可能有一个周期刚出现一半。闸门时间到了,那就只有半个周期,只能舍弃或者当做一个整个周期来看,因为计次只有整数,不可能计次0.5个数,那在这个过程,那就会出现多计一个,或者少计一个的请况,这就叫正负1误差,
测周法也有,在标准频率fc计次,在最后时刻,有可能一个数刚数到一半,计时就结束了,那这个半个数也只能舍弃或者按一整个数来算了。这里也会出现正负1的误差,
所以说正负1误差是这两种方法固有的误差,要想减小正负1误差的影响,就只能尽量多计一些数,当计次N比较大时,正负1对N的影响就会很小。那当有1个频率,测频法和测周法计次的N相同,就说明误差相同,这就是中界频率。把测频法的N和测周法的N提出来,令两个方达N相等,把fx解出来。得到中界频率fm。
对应图上,当待测信号频率小于中界频率时,测周法误差更小,选用测周法更合适,当待测信号频率大于中界频率时,测频法误差更小,选用测频法更合适。
接下来用STM32来实现这两种方法:
之前写过:对射式红外传感器计次、定时器外部时钟。比如对射式红外传感器计次,每来一个上升沿计次+1,那我们再用一个定时器,定一个1s的定时中断,在中断里,每隔1s取一下计次值,这样每次读取的计次值就直接是频率。也是如此,每隔1s取一下计次。
本节使用的方法是测周法。
定时框图里 输入捕获的各部分电路:
从左到右:最左边是四个通道的引脚,参考引脚定义表,就能知道引脚是复用在哪个位置。然后引脚进来,这里有一个三输入的异或门,
这个异或门的输入接到了通道1,2,3端口,执行逻辑:当三个输入引脚的任何一个有电平翻转时,输出引脚就会产生一次电平翻转。之后输出通过数据选择器,到达输入捕获通道1,那输入捕获通道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模式,一个通道灵活切换两个引脚。和两个通道同时捕获一个引脚,这就是这里交叉一下的作用和目的。
TRC信号也可以选择作为捕获部分的输入,TRC信号这样设计也是为了无刷电机的驱动,知道一下就行了,暂时不用。
输入信号进行滤波和极性选择后,预分频器每个通道各有一个,可以选择对前面的信号进行分频,就可以触发捕获电路进行工作了,每来一个触发信号,CNT的值,就会想CCR转运一次,转运的同时,会发生一个捕获事件,这个事件会在状态寄存器置标志位,同时也可以产生中断,如果需要再捕获的瞬间,处理一些事情的话,这就是整个电路的工作流程。
比如我们可以配置上升沿触发捕获,每来一个上升沿,CNT转运到CCR一次,又因为这个CNT计数器是由内部的标准时钟驱动的,所以CNT的数值,其实就可以用来记录两个上升沿之间的时间间隔,这个时间间隔就是周期,再取个倒数,就是测周法测量的频率了。这里有个细节问题,就是每次捕获之后,都要把CNT清0一次,这样下次上升沿再捕获的时候,取出的CNT才是连个上升沿的时间间隔,这个在一次捕获后自动将CNT清零的步骤,我们可以从主从触发模式,自动来完成。
输入捕获通道1更详细的框图:
基本功能都是一样的,引脚进来,还是先经过一个滤波器,滤波器的输入是TI1,就是CH1的引脚,输出TI1F,就是滤波后的信号,fDTS是滤波器的采样时钟来源,下面的CCMR1寄存器里的ICF位可以控制滤波器的参数,那么滤波器具体是怎么工作呢,可以看一下手册,在CCMR1寄存器这里,描述是这几位定义了TI1输入的采样频率及数字滤波长度,以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平。连续N个值为低电平,输出才为低电平,如果信号出现高频抖动,导致连续采样N个值不全都一样,那输出就不会变化,这样就可以达到滤波的效果,采样频率越低,或者采样个数N越大,滤波效果就越好。在实际应用中,如果波形噪声比较大,就可以把这个参数设置大一些,这样就可以过滤噪声了。
捕获上升沿或者下降沿,用这个CCER寄存器里的CC1P位,就可以选择极性了,最终得到TI1FP1触发信号,通过数据选择器,进入通道1后续的捕获电路,得到TI1FP2触发信号,连通到通道2的后续电路,这里并没有画出来。总共是4种连接方式(交叉连接)。
然后经过数据选择器,进入后续捕获部分电路,CC1S位可以对数据选择器进行选择,之后的ICPS位,可以配置这里的分频器,可以选择不分频,2分频,4分频,8分频,最后CC1E位,控制输出使能或失能,如果使能了输出,输入端产生指定边沿信号,经过层层电路,到达最后边。就可以让这里的CNT的值,转运到CCR里面来。
这个TI1FP1信号和TI1的边沿信号,比如TI1FP1信号的上升沿触发捕获,那通过电路,TI1FP1还可以同时触发从模式,这个从模式里就有电路,可以自动完成CNT的清零。可以看出,这个从模式就是完成自动化操作的利器。
主从触发模式:(博主自命名,笔记)就是主模式,从模式,和触发源选择这三个功能的简称,
其中主模式可以将定时器内部的信号,映射到TRGO引脚,用于触发别的外设,所以这部分叫做主模式
从模式就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的云鼎,也就是被别的信号控制,所以这部分叫做从模式。
触发源选择,就是选择从模式的触发信号源的,可以认为它是从模式的一部分。触发源选择,选择指定一个信号,得到TRGI,TRGI去触发从模式,从模式可以在这个列表里,选择一项操作来自动执行。
如果想完成刚才所讲的任务,想让TI1FP1信号自动触发CNT清零,那触发源的选择,就可以选中TI1FP1,从模式执行的操作,就可以选择执行Reset的操作,这样TI1FP1的信号就可以自动触发从模式,从模式自动清零CNT,实现硬件全自动测量。有关的具体内容可以看手册
还有很多其他的高级功能,可以用主从触发模式来实现,然后主模式还可以选择复位,使能,比较脉冲,和4个OCREF信号,作为TRGO的输出,具体描述,可以看手册。(不要去计,知道有这么个东西在就可以了)
再往下,有从模式的触发源可选信号,可以选择这些信号去触发从模式,
触发后执行的操作:有很多。
复位模式就是清零
对应PPT就是三个图:主模式、触发源选择、从模式
在库函数里也非常简单,对应三个函数:调用函数,给个参数,就行了
把之前所有的东西结合到一起,得到两个图:
这两个图也分别对应了我们演示的两个代码的逻辑,
输入捕获基本结构:只使用了一个通道,目前只能测量频率。
右上角是时基单元,把时基单元配置好,启动定时器。CNT就会在预分频器之后的时钟驱动下,不断自增。CNT就是我们测周法用来计时计数的东西。经过预分频器之后的时钟频率,就是驱动CNT的标准频率fc。这里不难看出,标准频率=72MHz/预分频系数,然后下面输入捕获通道1的GPIO口,输入这样一个方波信号,经过滤波器和边沿检测,选择TI1FP1为上升沿触发,之后输入选择直连的通道,分频器选择不分频,当TI1FP1出现上升沿之后,CNT的当前计数值就会转运到CCR1里,同时触发源选择,选中TI1FP1为触发信号,从模式选择复位操作。这样TI1FP1的上升沿,也会通过上面这一路,去触发CNT清零,当然这里会有个先后顺序,肯定得是先转运CNT的值到CCR里去,再触发模式下给CNT清零,CNT的值转到CCR,同时0转移到CNT里面去。或者是非阻塞的同步转移,CNT的值转到CCR,同时0转移到CNT里面去。总之不会先清零,再捕获,要不然捕获值都是0了。这是两条路的执行逻辑。
左上角的图:信号出现一个上升沿,CCR1=CNT,就是把CNT的值转运到CCR1里面去,这是输入捕获自动执行的。然后CNT=0,这是从模式自动执行的。CCR1的值,始终保持为最新一个周期的计数值。这个计数值就是N,然后fc/N ,就是信号的频率。所以当我们想要读取信号的频率时,只需要读取CCR1得到N,再计算fc/N ,就行了。
注意事项:CNT的值是有上限的,ARR一般设置为最大65535,那CNT最大也只能计65535个数,如果信号频率太低,CNT计数值可能会溢出。
从模式触发源的选择,在这里看到只有TI1FP1和TI2FP2,没有TI3和TI4的信号,所以如果想会用从模式自动清零CNT,就只能用通道1和2,对于通道3和4,就只能开启捕获中断,在中断里手动清零了,不过这样,程序就会处于频繁中断的状态。比较消耗软件资源。
PWMI使用了两个通道同时捕获一个引脚,可以同时测量周期和占空比,上面部分的结构,和输入捕获一样。下面多了个通道,首先TI1FP1配置上升沿触发,触发捕获和清零CNT,正常地捕获周期。
这时我们再来一个TI1FP2,配置为下降沿触发,通过交叉通道,去触发通道2的捕获单元。
发生什么:最开始上升沿,CCR1捕获,同时清零CNT,之后CNT一直++ ,然后在下降沿这个时刻,触发CCR2捕获,所以这时CCR2的值,就是CNT从这里到这里的计数值,(脉宽),所以这时CCR2的值,就是CNT从这里到这里的计数值,就是高电平期间的计数值,CCR2捕获,并不触发CNT清零,直到下一次上升沿,CCR1捕获周期,CNT清零,CCR1就是一整个周期的计数值,CCR2就是高电平期间的计数值,用CCR2/CCR1就是占空比,这就是PWMI模式,使用两个通道来捕获频率和占空比的思路。
另外这里,你可以两个通道同时捕获第一个引脚的输入,这样通道2的前面这一部分就没有用到,当然也可以配置两个通道同时捕获第二个引脚的输入,这样我们就是使用TI2FP1和TI2FP2这两个引脚了,这两个输入可以灵活切换。
手册里对应输入捕获模式和PWM输入模式。
TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
它并不叫SetPrescaler,而叫PrescalerConfig这个是这个库的命名规范,都是一个意思,写入PSC,单独写入PSC,还有一个重装模式的参数,参数第一个TIMx,用定时器2就用TIM2,第二个Prescaler,就是要写入PSC的值,我们直接把外层函数的这个参数传进去,第三个ReloadMode 重装模式,(指定定时器预分频器的重装模式),这个参数可以是下面的其中一个值,第二个Immediate,预分频器立即重装,说白了还是影子寄存器,预装载,这个问题,就是你写入的值,是立刻生效,还是在更新事件生效。立即生效,可能会在值改变时产生切断波形的现象,在频率变化时,就会出现一个不完整的周期
那在更新事件生效,就是会有一个缓存器,延迟参数的写入时间,等一个周期结束后,在更新事件时,再统一改变参数。保证每个周期的完整。
代码就是打通电路图:
步骤:
1.RCC开启时钟,把GPIO和TIM的时钟打开
2.GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式
3.配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
4.配置输入捕获单元,包括滤波器、极性、直连通道还是交叉通道、分频器这些参数,用一个结构体就可以统一进行配置了
5.选择从模式的触发源,触发源选择为TI1FP1,这里调用一个库函数,给一个参数就行了
6.选择触发之后执行的操作,进行Reset操作,也是调用一个库函数就行了。 调用TIM_Cmd函数,开启定时器,
这样所有的电路就能配合起来,按照我们的要求工作了。
TIM_ICStructInit,可以给输入捕获结构体赋一个初始值,
TIM_SelectInputTrigger 选择输入触发源TRGI
TIM_SelectOutputTrigger 选择输出触发源TRGO
TIM_SelectSlaveMode 选择从模式
TIM_SetIC1Prescaler 配置通道1的分频器,这个参数结构体里也可以配置,是一样的效果。
TIM_GetCapture1 分别读取4个通道的CCR 这个函数和SetCompare1是对应的,读写的都是CCR寄存器
滤波器和分频器的区别:虽然两个都是计次的东西,但是滤波器计次,并不会改变信号的原有频率,一般滤波器的采样频率都会远高于信号频率,所以它只会滤除高频噪声,是信号更平滑,1KHz滤波之后仍然是1KHz,信号频率不会变化。
而分频器就是对信号本身进行计次了,会改变频率,1KHz2分频之后就是500Hz,4分频就是250Hz,
TIM_ICPolarity,极性,对应的就是边沿检测,极性选择的部分。
TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
TIM_PWMIConfig(选择定时器,取地址把结构体变量放过来)
ST公司怕我们麻烦,来快捷完成这个配置,就是我们之前说的TIM_PWMIConfig,在函数里,会自动把剩下的一个通道初始化成相反的配置。那函数里面就会顺带配置通道2,交叉,下降沿。比如我传入通道1,直连,上升沿,那函数里面就会顺带配置通道2,交叉,下降沿,可以快捷地把电路配置成PWMI模式的标准结构,
执行完这个函数,PWMI电路就配置好了,接着主从模式启动定时器,最后获取频率的函数,不用改。再写一个获取占空比的函数。
自己测自己不存在晶振误差,只会同频。 如果要测量别的信号, 数值可能会有些抖动了,后期可以再做一些滤波处理,
实际测量过程中,还会有晶振误差,比如STM32的晶振不是那么准,在计次几百几万次之后,误差积累起来,会造成一些影响。
测外部电路
测量频率的性能:测频率的范围:目前给的标准频率是1MHz,计数器最大只能到65535,所以测量的最低频率是1M/65535,这个值大概是15Hz,如果频率再低,计数器就要溢出了,所以最低频率就是15Hz左右,如果想要再降低一些低频频率的限制,可以把预分频再加大,这样标准频率就更低,所支持测量的最低频率也就更低。然后测量的上限,就是支持的最大频率,这个最大频率,并没有一个明显的界限,因为随着待测频率的增大,误差也会逐渐增大,如果非要找个频率上限,那就是标准频率1MHz,超过1MHz,信号频率比标准频率还高,就测不了,但是这个1MHz的上限并没有意义,因为信号频率接近1MHz时,误差非常大了,所以最大频率要看你对误差的要求。在这里如果要求误差等于千分之一是,频率为上限,那就是1MHz/1000=1KHz,如果想提高频率的上限,就要把PSC降低一点。
提高标准频率,上限就会提高,