【智能车学习】FTM模块

目录

什么是PWM?

FTM模块(FlexTimer Module)

EPWM模式(Edge-Aligned PWM (EPWM) mode)

代码

实例

正交解码模式(Quadrature Decoder mode)

代码


今天突然遇到一个问题,所以决定还是把智能车里用到的FTM模块好好来理一下吧。

什么是PWM?

       PWM全称是脉冲宽度调制,是现代电力电子控制里不可或缺的一项技术,其基本原理大家都懂,不懂得的隔壁左转百度。这里只贴一下定义:

       采样控制理论中有一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。PWM控制技术就是以该结论为理论基础,对半导体开关器件的导通和关断进行控制,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。

       这里有一个点值得提及,那就是他的适用范围:具有惯性的环节。这就是为什么伺服机构可以用PWM控制,因为它是惯性环节,这点很重要。

FTM模块(FlexTimer Module

       FTM全称FlexTimer Module (柔性定时器模块),它的工作框图如下:

       FTM模块的核心是一个16位计数器,该计数器的时钟来源可设置(由FTMx_SC寄存器中的CLKS设置),既可来自系统时钟System Clock,外部时钟 External Clock,也可来自MCG模块的 MCGFFCLK(MCG fixed frenquency clock)。一般情况下,只要不是对外部计数功能,我们都会采用系统时钟的 Bus Clock 为FTM提供时钟。
       FTM的时钟源可进行分频(由FTMx_SC寄存器中的PS设置):

       作为一个高级单片机里的定时器模块,FTM模块具有多种功能供用户使用,例如输入捕获,输出比较,PWM比较,PWM输出,AB相正交解码等等,他们通过FTMx_CnSC寄存器进行配置,如下图:

FTMx_CnSC 寄存器的配置

       值得注意的是,这个寄存器是每个通道都有的,意味着单个FTM模块的不同通道可以工作在不同模式下

       这其中我们用到的就是PWM输出(电机、舵机)和正交解码(编码器),下面分别介绍。

EPWM模式(Edge-Aligned PWM (EPWM) mode)

        EPWM模式全称为边缘对齐PWM模式,也就是输出依照边沿对齐,与之对应的是中心对齐模式(CPWM),在这里我们选择使用EPWM模式。

技术手册里EPWM模式的描述

       该模式下计数值主要依据(FTMx_CNV)计数值寄存器和(FTMx_MOD)系数值寄存器两者进行控制,也就是通过分别配置MOD和CnV来控制。其中EPWM周期由(MOD-CNTIN+0x0001)决定,脉冲宽度(占空比)由(CnV-CNTIN)决定。

CNTIN必须设置为0

       CNTIN这个系数在使用EPWM模式时必须设置为0,因此周期和脉宽就分别由:(MOD+1)(CnV)决定。

        那么问题来了?模块下各个通道间PWM频率是否可以不同?

        答案是不能,一组FTM模块下的各个通道如果输出PWM可以有不同的占空比,但不可以有不同的频率。原因是因为各个通道可以配置自己独立的 Channel Value(FTMx_CNV) 寄存器,但是他们只有一个公用的 Modulo(FTMx_MOD) 寄存器:

每组FTM模块公用一个Modulo寄存器,各个通道都有各自的Channel Value寄存器

代码

        当使用这个模式时,应该首先将上图对应通道的状态控制寄存器(FTMx_CnSC)对应位按上图配置。然后再配置时钟和分频。最后写入对应的计数值完成计数。具体代码如下(如果看不懂可以看下面的实例):

//@Src By ChenYX
/******************** 选择输出模式为 边沿对齐PWM *******************/
//通道状态控制,根据模式来选择 边沿或电平
FTM_CnSC_REG(ftmn, ch) &= ~FTM_CnSC_ELSA_MASK;
FTM_CnSC_REG(ftmn, ch)  = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

/******************** 配置时钟和分频 ********************/
FTM_SC_REG(ftmn)    = ( 0
                       | FTM_SC_PS(3)      //分频2^FTM_SC_PS,频率为 bus clock/8
                       | FTM_SC_CLKS(1)    //时钟选择,bus时钟 = system clock/2
                      );  
                        
/******************** 单个通道PWM频率 ********************/
/*********** EPWM的周期为 :MOD - CNTIN + 0x0001 *********/
/*********** EPWM的占空比为 : CnV-CNTIN *****************/

FTM_MOD_REG(ftmn)   = mod;                 //PMW频率=系统频率/2/(2^FTM1_SC_PS)/FTMn_MOD
FTM_CNTIN_REG(ftmn) = 0;     		//计数器初始化值CNTIN设置为0。
FTM_CnV_REG(ftmn, ch) = cv;			//写入计数值,设置脉冲宽度:CnV.
FTM_CNT_REG(ftmn)   = 0;  			//计数器开启(写任何值到此寄存器,都会加载 CNTIN 的值)

实例

        我们以手册里典型实例来举个例子:

典型的EPWM模式应用实例
寄存器名称 位所属 位范围 设置值 作用
FTMx_SC PS [2:0] 001B 配置预分频系数ps为2(2^1),对总线时钟进行二分频(也就是对总线时钟每记两次后归零)
CLKS [4:3] 01B 时钟源为系统时钟(System Clock)
FTMx_CNTIN INIT [15:0] 0x0000 计数器无初始值(无初始相位偏移)
FTMx_MOD MOD [15:0] 0x0004 PWM脉宽为 MOD + 1 = 4 + 1 = 5
FTMx_CnV VAL [15:0] 0x0002 高电平宽度为 VAL = 2

       现在,我们假设系统时钟(System Clock)为120Mhz
       则总线时钟(Bus Clock)为系统时钟一半60Mhz
       经过预分频计数器后频率再降低一半为30Mhz
       配置MOD寄存器为4,脉宽为5,则PWM频率等价为1/5=6Mhz
       配置CnV寄存器为2,则占空比为2/5=40%

       当然,这只是个例子,智能车里的伺服机构:电机、舵机是用不到这么高的频率的,舵机一般均为50Hz,电机一般5~20 KHz不等,其设置的依据主要是其是否会对电磁信号产生影响,具体可以自己配置。

正交解码模式(Quadrature Decoder mode)

       在现如今的比赛中,我们使用的大部分都是两相输出的增量型旋转编码器。这种编码器输出A、B两相脉冲,这两组脉冲不仅能够表示转速,还能表示方向,如图所示,A相和B相脉冲数均表示转数,但当A相信号相位超前时,表示正转;B相信号相位超前时,表示反转:

编码器输出脉冲

       编码器输出的两相脉冲需要靠单片机进行解码才能读取转速信息,FTM模块就提供了正交解码这种工作模式。通过这种模式,它可以将输入的A、B两相脉冲解码后得到计数值,进而我们就可以获得转速信息进行闭环控制。

       这张图简述了FTM正交解码的简单流程,输入的信号先经过同步器,再经过配置滤波后,两相信号会被送入FTM方向计数器,计算出方向后会再送入FTM计数器进行带方向的计数。

       正交解码模式下可以通过 Quadrature Decoder Control And Status(FTMx_QDCTRL)寄存器进行相关功能的配置。在该模式下有计数/方向编码模式(Count and direction encoding mode)和 AB相编码模式(Phase A and phase B encoding mode)。

       计数/方向编码模式:B相输入值用于指示计数方向,A相输入用于计数,FTM计数器在A相输入的每个上升沿进行计数,累加或递减由B相电平决定。

计数/方向编码模式    Count and direction encoding mode

      AB相编码模式:计数方向由AB相之间的关系决定,计数频率由A相B相输入信号决定。当A相或B相的信号出现跳变,即可触发FTM计数器改变。

AB相编码模式      Phase A and phase B encoding mode

       大家是不是都觉得我们应该使用的是第二种方式来计数呢?其实恰恰相反,我们的增量式编码器输出的信号是两相同值信号,采用的是图一的计数/方向编码模式。:

       这里肯定有个疑问,明明增量式编码器输出的是A、B两相信号,判断方向依靠的是相位前后,为什么还要用计数/方向模式呢?别急,我把上面的图标记一下:

       明白了吗?当我们采用A方案时,如果将B相信号用来计数,A相信号用来表示方向的话。如果正转,A相信号一直超前于B相信号,所以每当B相上升沿捕获的时候,表示方向的A相都为1,则记为正传,计数器+1。反之,当反转时,每当B相信号上升沿时,A相滞后均为0,所以为反转,计数器-1。

       那为什么不用AB相编码模式呢?道理也很简单,如图所示,A、B相信号只要有一个出现跳变时就会计数,那么最后获得的结果自然不是我们所需要的,不考虑临界情况的会是我们实际脉冲的两倍。

代码

       当使用正交解码模式时,我们只需要使能正交解码和FTM模块即可,下面是具体的代码:

//@Src By ChenYX
FTM_MODE_REG(ftmn)  |= FTM_MODE_WPDIS_MASK;  		//写保护禁止(不取消写保护无法使能FTM)
FTM_QDCTRL_REG(ftmn) |= FTM_QDCTRL_QUADMODE_MASK;	//使用计数/方向编码模式
FTM_CNTIN_REG(ftmn)   = 0;				//初始计数值为0
FTM_MOD_REG(ftmn)     = FTM_MOD_MOD_MASK;	        //将MOD容器设置为最大,用于正交解码
FTM_QDCTRL_REG(ftmn) |= FTM_QDCTRL_QUADEN_MASK;		//使能正交解码模式
FTM_MODE_REG(ftmn)  |= FTM_MODE_FTMEN_MASK;             //使能FTM
FTM_CNT_REG(ftmn)     = 0;                    		//计数器开启(写任何值到此寄存器,都会加载 CNTIN 的值)

       如果我们需要获得编码器的数值,那我们需要设置PIT中断,并在中断里读取 FTMx_CNT 寄存器里的COUNT数值,并在读取后将其清零:

//@Src By ChenYX
int16 val;
val = FTM_CNT_REG(ftmn);             //读取寄存器里的计数值
FTM_CNT_REG(ftmn) = 0;               //寄存器数值清空,为下一个周期脉冲计数做准备
return val;

如有疑问或错误,欢迎和我私信交流指正。
W.By ChenYX,未经授权,请勿转载!

over~

发布了20 篇原创文章 · 获赞 15 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/qq_42059060/article/details/104912968
今日推荐