2.14 TIM输出比较(定时器第二部分)

定时器的输出比较功能

STM32定时器的输出比较功能,这个输出比较功能还是比较重要的,他主要是用来输出PWM波形的,PWM波形又是驱动电机的必要条件,所以你如果想用STM32做一些有电机的项目,比如智能车、机器人等,那这个输出比较功能就要好好学学了。

本小节共要实现三个程序:

1.PWM驱动LED呼吸灯。

2.PWM驱动舵机。

3.PWM驱动直流电机。

输出比较简介

输出比较,它的英文是OC,全称是Output Compare,直译就是输出比较的意思。在库函数中经常会出现英文缩写,所以要了解一下。另外还有IC,全称是Input Capture,译为输入捕获。还有CC,全程是Capture/Compare,一般表示的是输入捕获和输出比较单元。这就是这些英文缩写,了解一下。

输出比较电路可以通过比较CNT计数器与CCR捕获/比较寄存器值的关系,来对输出电平进行置1、置0或者翻转的操作。用于输出一定频率和占空比的PWM波形。这就是输出比较模块的最主要的功能,就是输出一定频率和占空比的PWM波形,这个CNT和CCR是在哪里呢?

刚才我们说了CC就是捕获比较的意思,R就是Register,寄存器的意思,CCR就是捕获比较寄存器。

这个捕获比较寄存器是输入捕获和输出比较共用的,当使用输入捕获时,他就是捕获寄存器;当使用输出比较时,他就是比较寄存器。

那在输出比较这里,这块电路会比较CNT和CCR的值,CNT计数自增,CCR是我们给定的一个值。

当CNT大于CCR、小于CCR或者等于CCR时,这里输出就会对应的置1、置0,这样就可以不断地输出一个电平不断跳变的PWM波形了,这就是输出比较的基本功能。

我们接着讲下面的,每个高级定时器和通用定时器都拥有4个输出比较通道,并且高级定时器的前3个通道额外拥有死区生成和互补输出的功能。可以看上图输出比较电路的图片,有四个输出比较的通道,可以同时输出四路PWM波形,这四个通道都有各自的CCR寄存器,但他们是共用一个CNT计数器的。高级定时器的前三个输出比较通道还额外具有死区生成和互补输出的功能,这个是用于驱动三相无刷电机的,我们本课程暂时不作为重点内容。我们主要学习的是通用定时器的输出比较功能。

现在我们对这个输出比较的功能大概就清楚了,就是用来输出PWM波形的,那什么是PWM波形呢?

PWM简介

我们简单地介绍一下PWM波形,PWM,它的英文全称是Pulse Width Modulation,意思是脉冲宽度调制,这个PWM波形是一个数字输出信号,也是由高低电平组成的,像这个图里一样:,这样一个连续变化的电平信号。那要这个信号有什么用呢?在具有惯性的系统中,可以对一系列脉冲的宽度进行调制,来等效的获得所需要的模拟参量,常应用于电机控速等领域。也就是说使用这个PWM波形,是用来等效地实现一个模拟型号的输出。也就是我们最开始提的问题,数字输出端口控制LED,按理说LED只能有完全亮和完全灭两种状态,怎么能实现控制亮度大小的呢?那通过这个PWM波形就可以实现。我们让LED不断点亮、熄灭、点亮、熄灭,当这个点亮、熄灭的频率足够大时,LED就不会闪烁了,而是呈现出一个中等亮度,当我们调控这个点亮和熄灭的时间比例时,就能让LED呈现出不同的亮度级别,对于电机调速也是一样,我们以一个很快的频率,给电机通电、断电、通电、断电,那么电机的速度就能维持在一个中等速度,这就PWM的基本思想,看起来也是一个挺简单的方法,对吧?

PWM的秘诀就是,天下武功,唯快不破,只要我闪的足够快,你就发现不了我到底是闪着还是亮着。

当然PWM的应用场景必须要是一个惯性系统,就是说LED在熄灭的时候,由于余晖和人眼视觉暂留现象,LED不会立马熄灭,而是有一定的惯性,过一小段时间才会熄灭。电机也是,当电机断电时,电机的转动不会立马停止,而是有一定的惯性,过一会才停。这样具有惯性的系统,才能使用PWM。

在这个图也可以看出,这种高低电平跳变的数字信号,它是可以等效为中间这个虚线所表示的模拟量的。当上面的电平时间长一点,下面电平时间短一点的时候,那等效地模拟量就偏向于上面;当下面电平时间长一点,上面电平短一点时候,等效地模拟量就偏向于下面。

在使用PWM时,会有几个比较重要的参数,我们来看一下。

第一个参数就是频率,频率=1/TS,TS代表一个高低电平变换周期的时间,周期的倒数就是频率。PWM的频率越快,那它等效模拟的信号越平稳,不过同时性能开销就越大。一般来说PWM的频率一般都在几K到几十KHZ之间,这个频率就已经足够快了。

第二个参数就是占空比,占空比=TON/TS,TON是高电平的时间,TS是一个周期的时间,TON/TS是高电平时间相对于整个周期时间的比例,一般用百分比表示。比如占空比为50%,那就是高低电平时间相等的方波。占空比为20%,那就是高电平占20%,低电平占80%,占空比为100%,那就直接表示高电平不带变的。这就是占空比,占空比决定了PWM等效出来的模拟电压的大小,占空比越大,那等效地模拟电压就越趋近于高电平,占空比越小,那等效地模拟电压就越趋近于低电平,这个等效关系一般来说是线性的,比如高电平是5V,低电平是0V,那50%占空比就等效于中间电压,就是2.5V;20%占空比就等效于1/5的电压,就是1V。

第三个参数是分辨率,他等于占空比变化步距,比如有的占空比只能是1%、2%、3%等等这样以1%的步距跳变,那他的分辨率就是1%。如果可以1.1%、1.2%、1.3%等等这样以0.1%的步距跳变,那它的分辨率就是0.1%。所以这个分辨率就是占空比变化的精细程度,这个分辨率需要多高,得看你实际项目的需求。如果你既要高频率又要高分辨率,这就对硬件电路要求比较高了,不过一般要求不高的话,1%的分辨率已经足够用了。

这些就是PWM的知识点,使用PWM波形,就可以在数字系统等效输出模拟量,就能实现LED控制亮度,电机控速等功能了。

输出比较通道

那接下来我们就来具体的分析一下。定时器的输出比较模块是怎么来输出PWM波形的呢?

这里这个图是通用定时器的输出比较部分电路:

这个电路对应的就是这一部分电路,左边是CNT和CCR比较的结果,右边就是输出比较电路,最后通过TIM_CH1输出到GPIO引脚上。下面还有三个同样的单元,分别输出到CH2、CH3、CH4。

在这个图里,左边就是CNT计数器和CCR1第一路的捕获比较寄存器,他俩进行比较,当CNT>CCR1.或者CNT=CCR1时,就会给这个输出模式控制器传一个信号,然后输出模式控制器就会改变输出的PC1REF的高低电平,REF信号实际上就是指这里信号的高低电平,这个REF是reference的缩写,意思是参考信号。上面还有一个ETRF输入,这个是定时器的一个小功能,一般不用,不需要了解。

接着这个REF信号可以前往主模式控制器,你可以把这个REF映射到主模式的TRGO输出上去,不过REF的主要去向还是下面这一路,通过下面这一路到达极性选择,给CC1P寄存器写0,信号就会往上走,就是信号电平不翻转,进来啥样出去就还是啥样,写1的话,信号就会往下走,就是信号通过一个非门取反,那输出信号就是输入信号高低电平反转的信号了,这就是极性选择,就是选择要不要把高低电平反转一下。

那接着就是输出使能电路了,选择要不要输出,最后就是OC1引脚,这个引脚就是CH1通道的引脚,在引脚定义表里就可以知道具体是哪个GPIO口了。

那现在输出逇通道我们就知道了。接下来我们还需要看一下这个输出模式控制器他具体是怎么工作的。什么时候给REF高电平什么时候给REF低电平,我们看一下下面这个表,这就是输出比较的8种模式:

 

这输出比较的8种模式,也就是这个输出控制器里面的执行逻辑,这个模式控制器的输入是CNT和CCR的大小关系,输出是REF的高低电平。

里面可以选择多种模式来更加灵活的控制REF输出,这个模式可以通过寄存器来进行配置,你需要哪个模式就可以选哪个模式。

第一个模式是冻结,描述的是CNT=CCR时,REF保持为原状态。CNT=CCR时维持原状态,那其实这个CNT和CCR就根本没有用,所以你也可以把它理解成CNT和CCR无效,REF保持为原状态。这个模式也比较简单,他根本就不管CNT谁大谁小,直接REF保持不变,维持上一个状态就行了。这有什么用呢?比如你正在输出PWM波,突然想暂停一会输出,就可以设置成这个模式,一旦切换为冻结模式后,输出就暂停了,并且高低电平也维持为暂停时刻的状态,保持不变。

第二到第四这三个模式,匹配时置有效电平、匹配时置无效电平和匹配时电平翻转,这个有效电平和无效电平,一般是高级定时器里面的一个说法,是和关断、刹车这些功能配合表述的,它说的比较严谨,所以叫做有效电平和无效电平,在这里为了理解方便,你可以直接认为置有效电平就是置高电平,置无效电平就是置低电平这样就行了。这是那个模式都是当CNT与CCR值相等时,执行操作。第一个是CNT=CCR时,REF置有效电平,也就是高电平;第二个是CNT=CCR时,REF置无效电平,也就是低电平;第三个是CNT=CCR时,电平翻转,这些模式就可以用作波形的输出了,比如相等时电平翻转这个模式,这个可以方便的输出一个频率可调,占空比始终为50%的PWM波形。比如你设置CCR为0,那CNT每次更新请0时,就会产生一次CNT=CCR的事件,这就会导致输出电平翻转一次,每更新两次,输出为一个周期,并且高电平和低电平的时间是始终相等的,也就是占空比始终为50%。当你改变定时器更新频率时,输出波形的频率也会随之改变。他俩的关系是输出波形的频率=更新频率/2,因为更新两次输出才为一个周期,这就是这个匹配时电平翻转模式的用途。那上面这两个相等时置高电平和低电平,感觉用途不是很大,因为它们都只是一次性的,置完高或者低电平之后,就不管事了,所以这俩模式不适合输出连续变化的波形。如果你想定时输出一个一次性的信号,那可以考虑以下这两个模式。

第五和第六这两个模式,强制为无效电平和强制为有效电平,这两个模式是CNT与CCR无效,REF强制为无效电平或者强制为有效电平。这里这两个模式和冻结模式也差不多,如果你想暂停波形输出,并且在暂停期间保持低电平或者高电平,那你就可以设置成这两个强制输出模式。

第七和第八这两个模式,PWM模式1和PWM模式2,这两个模式就非常重要了,他们可以用于输出频率和占空比都可调的PWM波形,也是我们主要使用的模式。

在PWM模式1下,并且计数器为向上计数的情况下,它是CNT<CCR时,REF置有效电平;CNT≥CCR时,REF置无效电平。

在PWM模式1下,并且计数器为向下计数的情况下,它是CNT>CCR时,REF置无效电平;CNT≤CCR时,REF置有效电平。

这个情况比较多,我们一般都只是用向上计数,所以这里向下计数的描述我们暂时不看了,他们之间也只有大小关系、极性,这些东西不同,基本思想都是一样的。我们着重分析一个向上计数的就可以了。

在PWM模式2下,并且计数器为向上计数的情况下,它是CNT<CCR时,REF置无效电平;CNT≥CCR时,REF置有效电平。

在PWM模式2下,并且计数器为向下计数的情况下,它是CNT>CCR时,REF置有效电平;CNT≤CCR时,REF置无效电平。

经过观察可以发现,PWM模式2实际上就是PWM模式1的取反。改变PWM模式1和PWM模式2,就只是改变了REF电平的极性而已。

从这个图可以看到,REF输出之后还有一个极性配置,所以使用PWM模式1的正极性和PWM模式2的反极性最终的最终的输出是一样的。这里设计的比较灵活,输出模式里可以设置极性,最终输出之前也可以设置极性,那这就是两个模式的区别,所以使用的话,我们可以只使用PWM模式1,并且是向上计数,这一种模式就行了。那这种模式是怎么输出频率和占空比都可调的PWM波形呢?

在这里,我给出了输出PWM的基本结构,这也是我们本节课的重点内容。首先左上角是时基单元和运行控制部分,输出PWM暂时还不需要中断,配置好时基单元,这里的CNT就可以开始不断地自增运行了,然后,下面这里,就是输出比较单元了,总共有4路,输出比较单元的最开始,是CCR捕获比较寄存器,CCR是我们自己设定的,CNT不断自增运行,同时他俩还在不断进行比较,CCR后面就是输出模式控制器,图例是以PWM模式1为例子来讲解的,这里面是PWM模式1的执行逻辑,那他是怎么输出PWM波形的呢?

我们看一下右上角的这个图,这里蓝色线是CNT的值,黄色线是ARR的值,蓝色先从0开始自增,一直增到ARR,也就是99,之后清0继续自增。在这个过程中,我们再设置一条红色线,这条红色线就是CCR,比如我们设置CCR是30,之后再执行PWM模式1的逻辑,下面的绿色线就是输出。这样一直持续下去,REF的电平就会不断的变化,并且它的占空比是受CCR值的调控的,如果CCR设置的高一些,输出的占空比就变大,CCR设置的低一些,输出的占空比就会变小,这就是PWM模式的工作流程,这里REF,就是频率可调,占空比也可调的PWM波形。最终再经过极性选择,输出使能,最终通向GPIO口。这样就能完成PWM波形的输出了。

接下来我们就来再看一下PWM波形的参数是如何计算的吧。

PWM频率:通过图可以看出,PWM波形的周期始终和计数器的溢出更新周期相同,所以PWM的频率等于计数器的更新频率。

即 Freq = CK_PSC/(PSC+1)/(ARR+1) 。

占空比参数:看图可以知道,CNT是从0一直加到ARR,这里ARR是99,所以CNT一共是从0计到99共100个数。CNT从0计到CCR,比如CCR是30,注意这里在等于30的瞬间,就已经跳变为低电平了,所以CNT从0到29是高电平,总共是30个数的时间。

即 Duty = CCR/(ARR+1)。

由于计数器从0开始计数,到达ARR时会回到0,因此计数周期实际上是ARR + 1个计数单元:

如果ARR = 999,计数器从0计数到999,总共有1000个计数单元。

分辨率:分辨率就是占空比变化的步距,从上面这个图可以看出,CCR的值应该是在0到ARR+1这个范围内。CCR=ARR+1时,占空比刚好是100%,如果CCR再大一些,那占空比始终就是100%,没有意义了。所以CCR的变化范围取决于ARR的值,ARR越大,CCR的范围就越大,对应的分辨率就越大。所以总结一下公式就是 分辨率 = 1/(ARR+1)。注意这里定义的分辨率是占空比最小的变化步距。所以这个值是越小越好。你也可以把CCR的范围定义成分辨率,那就是值越大越好。总之就是占空比变化的越细腻,越好。

如果要求你输出一个频率为1KHz,占空比可任意调节,且分辨率为1&的PWM波形,那你会不会用这里的公式,来找到合适的参数呢?

大家先想一想,我们下一小节来进行操作。那到这里有关PWM输出的内容就讲完了。

舵机简介

舵机可以用PWM信号来控制舵机输出轴的角度。

舵机是一种根据输入PWM信号占空比来控制输出角度的装置。

我们看一下舵机的内部图:

在这里可以看到里面的结构有舵机上盖、输出轴、减速齿轮组、直流电机、舵机控制板和电位器。可以看出舵机其实并不是一种单独的电机,它的内部是由直流电机驱动的,它里面还有一个控制电路板,是一个电机的控制系统。大概的执行逻辑是,PWM信号输入到控制板,给控制板一个指定的目标角度,然后电位器会检测输出轴的当前角度,如果大于目标角度,电机就会反转,如果小于目标角度,点击就会正转。最终使输出轴固定在指定角度,这就是舵机的内部工作流程。

但不管怎么样,我们只需要知道,输入一个PWM波形,输出轴固定在一个角度就行了。

输入PWM信号的要求:周期为20ms(对应的就是50Hz),高电平宽度为0.5ms~2.5ms(就是占空比是这个范围)。

这个占空比对应的输出角度,可以看下图:

我们这是一个180度的舵机,输出轴的角度是-90度到+90度,或者你规定是0到180度,都是没有问题的。然后输入信号脉冲宽度,周期是20ms,也就是两个上升沿之间的时间是20ms。然后高电平的时间,如果是0.5ms,对应的角度就是-90度,如果是1ms对应的角度就是-45度,如果是1.5ms对应的角度就是0度。

你给个PWM。输出轴就会固定在一个角度,那实际应用的话,比如机器人、机械臂,可以用来舵机控制关节,遥控车遥控船可以用舵机来控制方向。还有一些其他的机械结构,都可以考虑用一下这个舵机。

这里的PWM波形其实是当做一个通信协议来使用的,跟之前说的用PWM等效一个模拟输出,关系不大。把PWM当成一个通信协议,也是一个比较常见的用法,因为很多控制器都有PWM输出的功能,而且PWM只需要一根信号线就行了,这也是一种应用形式。

舵机硬件电路

实际应用的话,GND就接GND,电源正的5V,这个是电机的驱动电源,一般电机都是大功率设备,它的驱动电源也必须是一个大功率的输出设备,如果能像图例一样单独提供供电,那就再好不过了,如果不能,那也要注意电源的功率是不是能达标。如果单独供电的话,供电的负极要和STM32共地,然后正极接在5V供电引脚上。对于我们套件的话,可以直接从STLINK的5V输出脚,引一根线,接到这里,这样就是使用USB的5V供电,也是可以带动的。最后的PWM信号线,直接接到STM32引脚上就行了,比如PA0。因为这个舵机内部是有驱动电路的,所以我们单片机的引脚可以直接接到这里来,我们这个PWM只是一个通信线,是不需要大功率的。

直流电机及驱动简介

因为直流电机是一个单独电机,里面没有驱动电路,所以我们就要外挂一个驱动电路来控制了。

直流电机是一种将电能转换为机械能的装置(就是通电就转),有两个电极,当电极正接时,电机正转,当电极反接时,电机反转。

直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作。这里需要注意一下,电机类器件基本上都属于大功率设备了,必须要加驱动电路才能控制,电机驱动电路也是一个研究的课题,现在市面上有很多驱动电路可以选择,比如TB6612、DRV8833、L9110、L298N等等,这些都是比较常见的电机驱动芯片,另外还有一些用分离元件MOS管搭建的电路,这个功率可以做的更大一些,当然也可以自己用MOS管来设计电路,这都是没问题的,感兴趣的话可以研究一下。

那我们本课程就直接使用TB6612这款电机驱动芯片来驱动电机了,使用现成的芯片还是挺方便的,别人都把电路设计好,集成在芯片里了,我们直接拿来用就行了。

TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向。这个芯片里面是有两路驱动电路的,可以独立的控制两个电机,又因为它是H桥型的驱动电路,里面一路有四个开关管,所以就可以控制正反转,像有些芯片,比如ULN2003,它里面一路就只有一个开关管,所以它就只能控制电机在一个方向上转。

下图是H桥电路的基本结构:,它是由两路推挽电路组成的,这个我们刚才也分析过,比如左边这个,上管道通,下管断开那左边输出就是接在VM的电机电源正极。下管导通,上管断开,那就是接在PGND的电源负极。如果有两路推挽电路,中间这里接一个电机,左上和右下导通,电流就是从左边流向右边,右上和左下导通,那电流方向就反过来了,从右边流向左边。H桥可以控制电流流过的方向,所以他就能控制电机的正反转,这就是这个电机驱动芯片内部的部分电路。我们大概了解一下即可,应用的话,也不用管那么多。

电机驱动模块电路

那我们接下来看一下怎么用这个驱动芯片吧,我们看一下硬件电路。

这个就是电机驱动模块的硬件电路了。

这里的VM就是电机电源的正极了,这个和刚才舵机的电源要求是一样的,要接一个可以输出大电流的电源。VM是电压驱动输入端,范围是4.5V到10v。这个电压一般和你的电机额定电压保持一致,比如你是5V的电机,就接5V,如果你是7.2V的电机,就接7.2V。

下一个引脚是VCC,这个是逻辑电平输入端,范围是2.7到5.5V。这个要和我们控制器的电源保持一致,比如你使用STM32,是3.3V的器件,那就接3.3V,如果是51单片机,是5V的器件,那就接5V,这个引脚并不需要大功率,所以可以和控制器共用一个电源。

第三个引脚是GND,这个接系统的负极就行了,然后板子的右边还有两个GND,这个都是一样的引脚,在板子内部都是连通的,随便一个GND用就行了。

AO1、AO2、BO1、BO2就是两路电机的输出了,可以像图例这样接分别接两个电机。AO1和AO2就是A路的两个输出,他的控制端就是上面这三个,PWMA、AIN2和AIN1,这三个引脚控制下面A路的一个电机。这三个引脚直接接到单片机的GPIO口就行了,其中PWMA引脚要接到PWM信号的输出端,其他两个引脚可以任意接两个普通的GPIO口,那这三个引脚给一个低功率的控制信号,驱动电路就会从VM汲取电流,来输出到电机,这样就能完成低功率的控制信号控制大功率设备的目的了。

最后还剩一个STBY(Stand By)引脚,这个是待机控制脚,如果接GND,芯片就不工作,处于待机状态;如果接逻辑电源VCC,芯片就正常工作。这个引脚如果不需要待机模式的话,直接接VCC,3.3V。如果需要的话,可以任意接一个GPIO,给高低电平就可以控制了。

这就这个电机驱动板的硬件电路,那PWMA、AIN2和AIN1是如何控制电机正反转和速度的呢?

我们可以看一下这个表:

如果IN1和IN2全都接高电平,两个输出O1和O2都是低电平,这样两个输出没有电压差,电机是不会转的。

如果IN1和IN2全都接低电平,两个输出直接关闭,这样电机也是不会转的。

全高或者全低电机都不能转。

这里如果IN1给低电平,IN2给高电平,电机就处于反转状态,那转还是不转呢?要取决于PWM,如果PWM给高电平,那输出就是一低一高,有电压差了,电机可以转,这时候定义的是反转,开始转了。如果PWM给低电平,那输出两个低电平,电机还是不转。这就是反转的逻辑。

反转 : IN1给低,IN2给高,PWM高转低不转。

如果PWM是一个不断翻转的电平信号,那电机不就是快速的反转、停止、反转、停止了嘛。如果PWM的频率足够快,那电机就可以连续稳定的反转了,并且速度取决于PWM信号的占空比,这就是反转的工作流程。

正转:IN1给高,IN2给低,PWM高转低不转。

在这里的PWM就是我们之前讲的,使用PWM来等效一个模拟量的功能了。

那有关 电机驱动模块的介绍,到这里就讲完了。