EPWM模块功能
- EpwmA epwmB输出可以用作:
- 单边操作
- 双边缘对称操作
- 双边缘不对称运算
- 死区时间可以配置
- 可以配置TZ事件,并且可以设置HI和LO输出的逻辑状态。
- 可以配置ADC的中断事件或SOC事件。
让我们更接近主要模块:ePWM模块由什么组成以及与之连接的内容。
从图中可以看出,ePWM模块中没有很多块。因此,考虑每个模块负责什么并从信号开始是有意义的。
- EPWMxA和EPWMxB信号可能是最明显的输出信号。正常逻辑状态为HI或LO,具体取决于配置输出动作的方式
- TZ1 — TZ6 — . , , , . , EPWMxA EPWMxB . , , - , , . . , .
- EPWMxSYNCI EPWMxSYNCO — , , .
- EPWMxSOCA和EPWMxSOCB信号-此处的所有内容都比名字更清晰。这些事件可以设置ADC的SOC事件。
- EPWMxTZINT和EPWMxINT信号-此处是TZ以及与PWM本身相关的事件的中断事件,例如,在PWM周期产生中断。
现在让我们进入
时基(TB)模块-该模块负责每个ePWM模块的事件时间。我们不会介绍该模块的所有设置,我认为足够注意计数器有3种工作模式这一事实:
- 上下计数模式
- 递增计数模式
- 倒数模式
通过设置TBCLKSYNC
计数器比较(CC)位模块,还有一个定时器同步设置-通过它我们可以设置占空比。
动作限定符(AQ)模块-通过它可以配置事件的状态。对于输出,您可以配置以下操作:
- 设为HI状态
- 设置为LO状态
- 执行状态反转
- 没事做
死区子模块(DB)模块-该模块可用于设置PWM通道的死区。晶体管键不会立即切换对任何人来说都不是秘密,并且为了避免上半桥键没有时间关闭而下半键已经打开的情况,它们设置了切换到HI状态和更早切换到LO状态的延迟。
防区分区子模块(TZ)模块-如上所述,此模块与处理紧急情况相关联。在这里,我们可以选择4个动作之一。
- 设为HI状态
- 设置为LO状态
- 设置高阻状态
- 没事做
触发TZ模块动作的事件可以由软件和硬件触发。另外,提供了一个中断调用。
现在,让我们从言语转向实践。
首先,您需要为替代的epwm功能配置GPIO
EALLOW;
// pull-up
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0x000;
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0x000;
// GPIO EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0x001;
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0x001;
EDIS;
接下来,当我们已经配置了GPIO时,我们可以继续进行不同的设置。要配置PWM操作,您需要决定我们想要得到什么。让我们从TBCLK频率开始。它由以下公式确定:
在这里,您需要注意一个事实,即CLKDIV默认为1,而HSPCLKDIV则不同,默认为2。这是要记住的,因为有时人们会忘记它。当将程序加载到RAM中时,通常分别为HSPCLKDIV = 1,不会立即注意到此问题。
我们已经决定了TBCLK的时钟频率。但是我们必须选择计数器如何为我们工作。通过衰退,通过增加,也许通过这种方式,为此,您需要配置适当的寄存器,例如:
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
将来,没有人会被宏吓倒,我们将确定它们的来源。这些定义在名为DSP2833x_EPwm_defines.h的文件中定义。
然后,您需要确定我们的GPIO对达到某些TBCTR值的反应。有足够多的选择。它们显示在下表中:
然后,您需要确定我们想要从端口A和B获得什么行为,即,我们希望它们彼此连接或能够独立工作。如果我们希望端口A作为主端口,那么我们只需为它写下操作(例如,向上计数的情况):
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
如果我们想要第二个端口的独立性,则添加:
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
有关设置的更多详细信息,您只需要参考上图即可,AQCTLA寄存器比表中显示的要多一些,这不会改变图片,但是仅介绍有关计数器达到所需值的详细信息,例如,当计数时顶部或倒数。有关这些位的更简要信息,可以在系统.h文件的剪切中找到。
struct AQCTL_BITS { // bits description
Uint16 ZRO:2; // 1:0 Action Counter = Zero
Uint16 PRD:2; // 3:2 Action Counter = Period
Uint16 CAU:2; // 5:4 Action Counter = Compare A up
Uint16 CAD:2; // 7:6 Action Counter = Compare A down
Uint16 CBU:2; // 9:8 Action Counter = Compare B up
Uint16 CBD:2; // 11:10 Action Counter = Compare B down
Uint16 rsvd:4; // 15:12 reserved
};
如果我们有2个独立工作的ePWM端口,并且想要设置死区时间,则需要将寄存器设置为所需状态,例如:
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
现在我们已经确定了外围设备的描述,我们可以继续进行具体的示例。
在计数模式下配置ePWM
这是一个没有停滞时间并且端口A和端口B独立工作的示例。当A处于活动状态时,B处于非活动状态。
EPwm1Regs.TBPRD = 150000 / 5; // . 150 / 5000
// 50%
EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD / 2;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLB.bit.PRD = AQ_SET;
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;
在示波器上,您可以看到获得的结果:
现在您可以尝试添加空载时间,为此,我们添加:
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.all = BP_ENABLE + POLSEL_ACTIVE_HI_CMP; // db
EPwm1Regs.DBFED = 300; // = 150 * 2 = 300
EPwm1Regs.DBRED = 300;
根据以下公式,空载时间的计算方法与频率相同:
现在我们按照自己想要的方式得到了死时间,
如果我们需要解开端口A和端口B怎么办?这也会发生。这里的一切都很简单。我们回到第一个示例,删除最后4行,并将每个占空比写入以下寄存器。
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD / 2; // 50%
EPwm1Regs.CMPB = EPwm1Regs.TBPRD / 3; // 33%
现在我们有这样一张照片。您可以分别设置每个通道的占空比。
对于衰减模式,一切都大致相同。上下模式中的倒数有所不同。匀场频率使用以下公式计算:
死区时间也是如此。
也许没有考虑的唯一重要的事情是TZ设置,现在让我们更详细地介绍这个模块。
要以编程方式触发警报事件,只需配置以下寄存器即可:
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
可以使用以下命令来调用和重置PWM警报:
//
EALLOW;
EPwm1Regs.TZFRC.bit.OST = 0x001;
EDIS;
//
EALLOW;
EPwm1Regs.TZCLR.bit.OST = 0x0001;
EDIS;
如果要在硬件中调用TZ信号,则一切都变得更加容易,通过TZSEL寄存器设置所需的TZ,但除此之外,我们需要将GPIO配置为TZ。
结论
如果有人觉得这篇文章有趣,那么我可以以或多或少的加速方式写几篇文章。我打算考虑使用can模块,我想对它进行dma,也许我还将与他们的库一起从ti撰写有关IQMath的小文章。