赞
踩
本学习教程,参考B站江科大自化协STM32视频,型号为STM32F103C8T6。
本文讲重点讲述TIM输出比较功能。
OC(Output Compare)输出比较,输出比较这个模块最常见的功能就是产生PWM波形,用于驱动电机等设备。输出比较可以通过比较CNT(计数器)与CCR(捕获/比较寄存器)寄存器值的关系,CNT计数自增,CCR是我们给定的值,通过对比来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生成和互补输出的功能。
PWM(Pulse Width Modulation)脉冲宽度调制,PWM波形是一个数字输出信号,也是由高低电平组成。在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域。使用PWM波形是为了等效地实现一个模拟信号地输出。PWM的秘诀就是天下武功唯快不破,只要闪的快,就发现不了是闪着亮的,还是一个正常、平稳的亮度。PWM应用需要在惯性的系统,LED熄灭的时候,由于余晖和人眼视觉暂留现象,LED不会立马熄灭,而是有一定的惯性,过一小段时间才会熄灭;电机断电时,电机不会立马停止,而是有一定的惯性,过一会才停。
从下图可看出高低电平跳变的数字信号,可以等效为中间虚线所表示的模拟量。当上电平时间长,下电平时间短时,等效的模拟量就偏上,反之亦然。
PWM重要参数:
频率 = 1 / TS
占空比 = TON / TS
分辨率 = 占空比变化步距 (占空比变化1%2%3%,以1%的步距跳变,分辨率1%,分辨率就是占空比变化的精细程度)
通用定时器的输出比较通道,左边时CNT和CCR比较的结果,右边是输出比较电路,最后通过TIMx_CH1输出到GPIO引脚上。
CNT和CCR比较后,就会给输出模式控制器一个信号,依此改变输出OC1REF的高低电平。REF为reference的缩写,意思为参考信号;REF信号可以前往主模式控制器,可以映射到主模式的TRGO输出上去;REF主要去向是到达极性选择寄存器,给寄存器写0信号就会走上路,即信号电平不翻转,进来啥样,出去啥样,写1的话,信号就会往下走,经过一个非门取反,输出信号就是输入信号高低电平反转的信号,这就是极性选择,就是选择是不是要把高低电平反转一下;接着就是输出使能电路,选择要不要输出,最后就是OC1引脚(TIMx_CH1通道的引脚)。
注:ETRF输入,这是定时器的一个小功能,一般不用。
输出模式控制具体工作模式如下表所示,共八种模式,即执行逻辑,此模式可以通过寄存器来配置,需要哪个模式选择哪个模式。
(1)冻结模式,一旦切换此模式,输出就暂停,并且高低电平也维持为暂停时刻的状态,保持不变;
(2)匹配时三种模式,有效电平和无效电平是高级定时器的说法,是和关断、刹车这个功能配合表述的,说的比较严谨,所以叫有效电平和无效电平,为了理解方面,置有效电平就是置高电平,置无效电平就是置低电平,这三个模式都是当CNT与CRR值相等时,执行操作。电平翻转模式可以方便地输出一个频率可调,占空比始终为50%的PWM波形,比如设置CCR为0,那CNT每次更新清0时,就会产生一次CNT=CCR的事件,这就会导致输出电平翻转一次,每更新两次,输出为一个周期,这就是一个占空比50%的PWM波形。当改变频率时,输出波形的频率也会随之改变。输出波形的频率=更新频率/2,更新两次,输出才为一个周期。如果想输出定时一次性不改变的信号,可以考虑上两个模式。
(3)强制为无效电平和强制为有效电平。如果想暂停波形输出,并且在暂停期间保持低电平或高电平,那可以设置这两个强制输出模式
(4)PWM模式。可用于输出频率和占空比都可调的PWM波形。PWM2实际上时PWM1的输出取反,改变PWM1和PWM2只是改变REF电平的极性。下图左上角时时基单元和运行控制部分,再左边是时钟源选择(省略了),只不过ARR与CNR产生的中断事件申请不需要了,输出PWM不需要中断。配置好时基单元,CNT开始自增运行。下面为4路输出比较单元,最开始是CCR捕获比较器(自己设置),然后就是输出模式控制器(以PWM模式1为例),如何输出PWM波形的呢?看右上角图,蓝色线是CNT的值,黄色线是ARR的值,蓝色线从0开始自增,一直增到ARR(设为99),之后清0再继续自增,在这过程中再设置一条红色线,这条红色线就是CCR,比如我们设置CCR为30,之后再执行下面的逻辑,绿色线就是输出。当CNT<CCR时,置高电平;当CNT≥CCR时,置低电平,当CNT溢出清0后,CNT<CCR,又置高电平。依此循环,REF的电平就会不断变化,并且占空比受CCR的值调控,CCR设置高一些,输出的占空比就大,反之亦然。REF就是一个频率可调,占空比也可调的PWM波形,最终再经过极性选择,输出使能,通向GPIO口,完成PWM波形的输出。
PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1) 对应计数器的更新频率
PWM占空比: Duty = CCR / (ARR + 1)
PWM分辨率: Reso = 1 / (ARR + 1)
提问:要求输出一个频率为1kHz,占空比可任意调节,分辨率为1%的PWM波形?
分辨率1%=1/(ARR+1),求得ARR=99,单片机的预分频器的输入时钟CK_PSC=72MHz(来自内部时钟),即1kHz = 72MHz/ (PSC + 1)/100,PSC预分频器值为719。
下图为高级定时器输出比较通道。圈外与通用定时器电路一样。圈内需要与外部电路一起理解。外部电路是两个MOS管开关,而OC1和OC1N分别控制上MOS管和下MOS管导通和关闭,在切换上下管导通状态时,如果在上管关断的瞬间,下管立刻就打开,可能会因为器件的不理想,上管还没完全关断,下管就已经导通了,出现短暂的上下管同时导通的现象,会导致功率损耗,引起器件发热,在这里为了避免这个问题,就有了死区生成电路,它会在上管关闭的时候,延迟一小段时间,再导通下管,下管关闭的时候,延时一小段时间,再导通上管,避免上下管同时导通。
在PA0一脚输出一个PWM波,驱动LED呈现不同的亮度。
Hardware下新建PWM.c和PWM.h文件
打通这些PWM模块,即可完成配置。
查看库函数tim.h,拖到最下面
(1)TIM_OC1Init、TIM_OC2Init、TIM_OC3Init、TIM_OC4Init,配置输出比较单元,OC(Output Compare),一个函数配置一个单元,参数1选择定时器,参数2为结构体,即输出比较那些参数。
(2)TIM_OCStructInit这个用来给输出比较结构体赋一个默认值,完成这个,输出比较的配置就完成了。
(3)TIM_ForcedOC1Config、TIM_ForcedOC2Config、TIM_ForcedOC3Config、TIM_ForcedOC4Config四个函数用来配置强制输出模式,如果在运行中想要暂停输出波形并且强制输出高电平或低电平,可用此函数。用的比较少,因为强制输出高电平就是设置100%占空比一样的,强制低电平就是0%占空比。
(4)TIM_OC1PreloadConfig等四个函数是用来配置CCR寄存器的预装功能,预装功能就是影子寄存器,就是写入的值不会立即生效,而是等到更新事件才会生效,一般不用。
(5)TIM_OC1FastConfig等四个函数是用来配置快速使能,手册里单脉冲模式,有介绍,用的不多。
(6)TIM_ClearOC1Ref等四个函数,在手册里外部事件清除REF信号有介绍,用的不多。
(7)TIM_OC1PolarityConfig等这7个函数用来单独设置输出比较的极性,带N就是高级定时器里互补通道的配置,OC4无互补通道,所以就没有OC4N。在这里可以设置极性,在结构体初始化也可以设置极性,作用一样,结构体中是一起初始化,而这里是单独函数修改。
(8)TIM_CCxCmd单独用来修改输出使能参数。
(9)TIM_SelectOCxM选择输出比较模式,单独更改输出比较模式的函数
(10)TIM_SetCompare1、2、3、4单独更改CCR寄存器值得函数,此四个函数比较重要,运行时更改占空比需要用到。
(11)TIM_CtrlPWMOutputs仅高级定时器使用,输出PWM时需要调用这个函数,使能输出,否则PWM将不能正常输出。
把要用的TIM外设和GPIO外设时钟打开,并选择内部时钟。
包括前面的时钟源选择、时基单元都配置好。
包括CCR的值、输出比较模式、极性选择、输出使能这些参数,在库函数里用结构体统一配置。不同的GPIO口对应的输出比较通道也不同。 只配置通用定时器的所需要的,但当需要用高级定时器,需要把结构体成员配置完整 。
把PWM对应的GPIO口,初始化为复用推挽输出的配置。PWM与GPIO对应关系参考引脚定义表。TIM2_CH1对应的时PA0引脚,也可以利用AFIO复用其他引脚(表中可查)
GPIO_Mode要选择复用开漏输出,普通的开漏推挽输出,引脚控制权来自于输出数据寄存器,想用定时器来控制引脚,就需要用复用开漏/推挽输出的模式,在这里输出数据寄存器将被断开,输出控制权将转移给片上外设,这里片上外设引脚连接的就是TIM2_CH1通道。所以只有在复用推挽模式,引脚控制权才能交给片上外设,PWM波形才能通过引脚输出。
启动计数器,输出PWM
PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1) 对应计数器的更新频率
PWM占空比: Duty = CCR / (ARR + 1)
PWM分辨率: Reso = 1 / (ARR + 1)
提问:要求输出一个频率为1kHz,占空比50%,分辨率为1%的PWM波形?
(1)分辨率1%=1/(ARR+1),求得ARR=99;
(2)单片机的预分频器的输入时钟CK_PSC=72MHz(来自内部时钟),即1kHz = 72MHz/ (PSC + 1)/100,求得PSC=719;
(3)50% = CRR/100,求得CRR=50;
注意:占空比是CRR与ARR+1的比值,当ARR变化时,占空比也会改变。
引脚重映射,TIM2_CH1对应的时PA0引脚,如何重映射为PA15引脚,需要利用AFIO复用。
(1)首先开启AFIO时钟
(2)GPIO引脚重映射配置
查手册8.3.7 定时器复用功能重映射。
(3)关闭调试端口的复用(针对有复用的端口)
PA15上电后默认复用为调试端口JTDI,所以如果想让他作为普通的GPIO或者复用定时器的通道,还需要先关闭调试端口的复用。
第三个千万不要使用,会导致SWD、JTAG都失效
(4)修改GPIO初始化
舵机是一种根据输入PWM信号占空比来控制输出角度的装置。PWM信号输入到控制板,给控制板一个指定的目标角度,然后这个电位器检测输出轴的当前角度,如果大于目标角度,电机就会反转,如果小于目标角度,电机就会正转,最终使输出轴固定在指定角度。输入一个PWM波形,输出轴固定在一个角度。
输入PWM信号要求:周期为20ms,对应50Hz,高电平宽度为0.5ms~2.5ms。此时PWM波形当作一个通信协议来使用,跟之前说的,用PWM等效一个模拟输出,关系不大,这种当作通信协议的方式,也是比较常用。
舵机的硬件电路比较简单
需要用到PA0引脚输出PWM。
也可以多配置几个PWM通道,对于同一定时器的不同通道输出的PWM,因为不同通道共用一个计数器所以他们频率一样,而占空比由各自的CCR决定;因为计数器更新,所有PWM同时跳变,所以它们的相位同步。
驱动多个舵机或者直流电机,使用同一个定时器不同通道的PWM,使用TIM_SetCompare1、2、3等改变不同通道的PWM,就完全可以。
设置函数,舵机设置角度(0~180°),调用即可改变为对应的角度。Hardware下新建Servo.c和.h文件。
直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转。
直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作。常见电机驱动电路有:TB6612、DRV8833、L9110、L298N等,TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向。电路由两路推挽电路组成,左边上管导通,下管断开,左边输出就是接在VM的电机电源正极;下管导通,上管断开,左边输出就是接在PGND的电机电源负极。如果有两路推挽电路,中间接一个电机,左上和右下导通,那电流就是从左边向右边,右上和左下导通,那电流方向就反过来,从右边流向左边,H桥可以控制电流流过的方向,所以能控制电机正反转。
驱动芯片的硬件电路如下图所示。
VM要接一个可以输出大电流的电源,VM是驱动电压输入端,范围4.5~10 V,一般和电机的额定电压保持一致。
VCC逻辑电平输入端,范围2.7~5.5V,与控制器的电源保持一致。
GND接系统的负极。三个GND都是连通的。
AO1、AO2、BO1、BO2是两路电机的输出,分别接两个电机。
STBY工作/待机状态控制输入端,接GND芯片不工作,处于待机状态,接逻辑电源VCC,芯片正常工作,若不需要待机模式,可以直接接VCC3.3,若需要任意接一个GPIO,给高低电平即可控制。
IN1给低电平,IN2给高电平,PWM高电平时转低电平时不转,若PWM是一个不断翻转的电平信号,电机就快速地反转、停止、反转、停止,PWM频率足够快,那电机就可以连续稳定地反转了,并且速度取决于PWM信号地占空比,这就是反转的工作流程。这里PWM就是前文讲的,用来等效一个模拟量的功能。
PWMA——PA2;AIN1——PA4;AIN2——PA5;按键——PB1
在呼吸灯程序上修改,目前此代码为通道1输出一个1kHz的PWM,电机接到通道3上,所以要修改一下PWM。
按下按键速度+20,从-100到100。
测试时发现,电机内部会发生蜂鸣器一样的声音,这时因为电机也是线圈和磁铁,在PWM驱动下就会发出蜂鸣器的声音,正常现象。若想避免,需要提高PWM频率,PWM频率足够大时,超出人耳范围,人耳就听不到了。人耳听到频率范围为20Hz到20kHz,目前给的频率时1kHz,人耳可以听到,在这里可以加大频率,加大频率可以通过预分频器PSC来完成,不影响占空比。
完成PWM波形输出驱动呼吸灯、舵机、电机
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。