This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/LAUNCHXL-F28379D:五通道 ePWM

Guru**** 2539500 points
Other Parts Discussed in Thread: TMS320F28379D

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/607575/ccs-launchxl-f28379d-five-channel-epwm

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:TMS320F28379D

工具/软件:Code Composer Studio

您好!

我已经制作了一个代码来生成三相 PWM 和 H 桥 PWM 信号、下面是我的代码。

三相 PWM 信号(ePWM 1 - 3)应彼此同步、而 H 桥 PWM 信号(ePWM 4 - 5)应彼此同步。

三相 PWM 信号的基波频率为250Hz、开关频率为25kHz。

H 桥 PWM 信号使用相移控制、开关频率为100kHz。

现在我有三个问题:

(1)如果我正确理解 TMS320F28379D 的数据表、则系统时钟为200MHz。 TMS320F28379D 的数据表还显示:对于100MHz 以上的 SYSCLK、EPWMCLK 必须是 SYSCLKOUT 的一半、这意味着如果 SYSCLKOUT=200MHz、ePWM 时钟应该为100MHz。 但是、如果我将 TBCTL.bit.HSPCLKDIV 和 TBCTL.bit.CLKDIV 都设置为1、那么 ePWM 时钟是否会被强制为200MHz?

此外、在我的代码中、我将 TBCTL.bit.HSPCLKDIV 和 TBCTL.bit.CLKDIV 都设置为1、如果 ePWM 时钟实际上是100MHz、 由于我需要25kHz 的开关频率、因此 ePWM 周期寄存器应设置为100 [MHz]/ 25 [kHz]/ 2 = 2000 (上-下计数模式)。 但是、它提供的开关频率为12.5kHz、因此我必须将 ePWM 周期寄存器设置为1000、才能获得25kHz 的开关频率。 这让我感到困惑。 为什么会这样呢?

(2)我尝试更新计数器=零时生成的 EPWM1 ISR 函数中的三相占空比。 每次调用 ISR 函数时、都会添加相移、以便电压基准矢量以250Hz 的频率旋转。

如果我设置 EPwm1Regs.ETPS.bit.INTPRD = et_3rd、这意味着每三个事件生成一次 INT、那么基频为正确的250Hz (每次调用 ISR 时、电压矢量相移都是上一个事件的3倍)。 但是、如果我将 EPwm1Regs.ETPS.bit.INTPRD 降低至 et_1st、即中断在每个开关周期发生、那么基频变得更低。

但是、如果我将 EPwm1Regs.ETPS.BIT.INTPRD 保持在 et_1st 并将开关频率降低至10kHz、即中断频率也降低至10kHz、那么基频就会变为正确的。

我认为这可能是因为中断功能太耗时、DSP 无法在一个开关周期内处理、从而导致一些中断同时丢失。 但是、我认为中断功能不是很长、由于 DSP 工作频率为200MHz、中断频率为25kHz、这意味着可以在一个开关周期内执行8000个计算步骤、我认为这应该远远超过要求。

对此有何解释和解决方案?

(3) ePWM 4和5根据"TMS320x280x 增强型脉宽调制器(ePWM)模块参考指南(SPRU791)"第3.9章 ZVSFB 转换器进行编程。 但是、EPWM4A 和5A 始终提供3.3V 电压、而 EPWM4B 和5B 始终提供0V 电压。这对我来说非常令人困惑。 希望有人能向我解释一下。

非常感谢!

//######################################################################################################################
//
//文件:ePWM_F5_channel.c
//
//三相 SVPWM
// 25kHz
//相位 A - EPWM1
//相位 B - EPWM2
//相位 C - EPWM3
//
// H 桥相移
// 100kHz
//相位 A - EPWM4
//相位 B - EPWM5
//

//######################################################################################################################
//包含的文件
//
#include "F28x_Project.h"
#include "math.h"

//######################################################################################################################
//定义

#define PI 3.141592653579793
#define two_PI 6.283185307179586
#define two_pi_over_three 2.094395102393195
#define sqrT_2 1.414213562373095
#define sqrT_3 1.732050807568877

//######################################################################################################################
//全局变量
//

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//直流链路电压
float32 u_dc = 48;//[V]

//α-β 坐标系中的电压基准
float32 u_ref_alpha;//[V]
float32 u_ref_beta;//[V]
float32 u_ref_angle;//[rad]
float32 u_ref_amp;//[rad]

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//三相逆变器 PWM
float32 f_믹 놾= 250;//[Hz]
float32 f_sw_thine_phase = 25e3;//[Hz]
//周期:递增和递减计数
uint16 N_three PHASE_SW_PERIOD = 1000;// ePWM 周期寄存器:n_three PHASE_SW_PERIOD = 100 [MHz]/25[kHz]/2 = 2000
//死区
uint16 N_th3_PHASE_DEADBADAND = 25;//死区寄存器:n_th3_PHASE_DEADBAND = 500 [ns]* 100 [MHz]/2 = 25
// PWM 基准更新
uint16 N_th3_PHASE_UPDATE = 1;//
// PWM 占空比:1表示100%
float32 Duty_sw[3];
//调幅指数:1表示100%
float32 m_a = 0.9;

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// SinePWM 或 SVPWM?
// 1:SinePWM
// 2:SinePWMTriangularInjection
// 3:SVPWM
uint16 PWM_Algorithm = 3;

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// SinePWMTriangularInjection
float32 u_ref_abc_max、u_ref_abc_min;
float32 u_try_ref;//三角注入

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// SVPWM
uint16 sector_sVPWM;

float32 Duty_SVPWM[3];

float32 u_ref_amp_SVPWM;
float32 u_ref_ang_SVPWM;
float32 u_ref_alpha_SVPWM;
float32 u_ref_beta_SVPWM;

// SVPWM 表
//[章节][a 或 b][状态]
UINT16 V_SVPWM_BASILE[6][2][3]=

//扇区1

{1、0、0}、//向量 A:相位 A B C
{1、1、0}//向量 B:相位 A B C
}、
//扇区2.

{0、1、0}、//向量 A:相位 A B C
{1、1、0}//向量 B:相位 A B C
}、
//扇区3.

{0、1、0}、//向量 A:相位 A B C
{0、1、1}//向量 B:相位 A B C
}、
//扇区4.

{0、0、1}、//向量 A:相位 A B C
{0、1、1}//向量 B:相位 A B C
}、
//扇区5.

{0、0、1}、//向量 A:相位 A B C
{1、0、1}//向量 B:相位 A B C
}、
//扇区6.

{1、0、0}、//向量 A:相位 A B C
{1、0、1}//向量 B:相位 A B C
}、
};

///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// H 桥逆变器 PWM
float32 f_sw_h_bridge = 100e3;//[Hz]
//周期:递增计数
uint16 N_H_BRIDGE_SW_PERIOD = 500;// ePWM 周期寄存器:n_H_BRIDGE_PERIOD = 100 [MHz]/100 [kHz]= 1000
//占空比
float32 Duty_H_bridge = 0.5;
uint16 N_H_BRIDGE_DUTY;
//死区
UINT16 N_H_BRIDGE_DEADBAND = 5;//死区寄存器:n_three 相位死区= 100 [ns]* 100 [MHz]/2 = 5


//######################################################################################################################
//函数原型
//
void InitEPwm1 (void);
空 InitEPwm2 (空);
空 InitEPwm3 (空);
void InitEPwm4 (void);
void InitEPwm5 (void);

_interrupt void epwm1_ISR (void);
//__interrupt void epwm2_ISR (void);
//__interrupt void epwm3_ISR (void);
//__interrupt void epwm4_ISR (void);
//__interrupt void epwm5_ISR (void);

void CurrentController (void);

void SinePWM (void);
void SVPWM (void);
void SinePWMTriangularInjection (void);

//######################################################################################################################
//索引
//
int16 i、j、k;

//
//
//主函
//
void main (void)

//
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2837xD_SYSCTRL.c 文件中。
//
InitSysCtrl();

//
//步骤2. 初始化 GPIO:
//此示例函数位于 F2837xD_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
//
InitGpio();

//
//启用 PWM1、PWM2、PWM3、PWM4、PWM5
//
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM4= 1;
CpuSysRegs.PCLKCR2.bit.EPWM5=1;

//
//在这种情况下、只需初始化 ePWM1、ePWM2、ePWM3、ePWM4、ePWM5的 GPIO 引脚
//这些函数位于 F2837xD_ePWM.c 文件中
//
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
InitEPwm4Gpio();
InitEPwm5Gpio();

//
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2837xD_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU 中断并清除所有 CPU 中断标志:
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable();

//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.EPWM1_INT =&epwm1_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//
//对于此示例,只初始化 ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=0;
EDIS;

InitEPwm1();
InitEPwm2();
InitEPwm3();
InitEPwm4();
InitEPwm5();

EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;

//
//步骤4. 特定于用户的代码、启用中断:
//

//
//启用连接到 EPWM1-3 INT 的 CPU INT3:
//
IER |= M_INT3;

//
//在 PIE 中启用 ePWM INTn:组3中断1-3
//
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

//
//启用全局中断和更高优先级的实时调试事件:
//
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

//
//步骤5. 空闲循环。 只需坐下来循环(可选):
//
for (;;)

ASM (" NOP");


//
// InitEPwm1 -初始化 EPwm1配置
//
空 InitEPwm1 (空)

//
//设置 TBCLK
//
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上/向下计数
EPwm1Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;//主模式
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;//相位为0
EPwm1Regs.TBCTR = 0x0000;//清除计数器
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;//无活动加载
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;//同步下行数据流

//
//将影子寄存器加载设置为零
//
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.CMPA.bit.CMPA = Duty_SW[0];//设置比较 A 值
EPwm1Regs.CMPB.bit.CMPB = Duty_SW[0];//设置比较 B 值

//
//设置操作
//
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;//在递增计数期间设置事件 A 上的 Pwm1A
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;//在递减计数期间清除事件 A 上的 Pwm1A

EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;//在递增计数期间清除事件 B 上的 Pwm1B
EPwm1Regs.AQCTLB.bit.CBD = AQ_SET;//在递减计数期间设置事件 B 上的 Pwm1B

//
//高电平有效互补 PWM -设置死区
//
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;//完全启用:同时启用 A 和 B
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm1Regs.DBRED.bit.DBRED = N_three 相位死区;//上升沿高互补
EPwm1Regs.DBFED.bit.DBFED = N_three 相位死区;//下降沿高互补

//
//中断,我们将在其中更改比较值
//
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;//在零事件时触发 INT ON
EPwm1Regs.ETSEL.bit.INTEN = 1;//启用 INT
EPwm1Regs.ETPS.bit.INTPRD = et_3rd;//在发生 N'n'事件时生成 INT


//
// InitEPwm2 -初始化 EPwm2配置
//
空 InitEPwm2 (空)

//
//设置 TBCLK
//
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上/向下计数
EPwm2Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;//从机模式
EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;//相位为0
EPwm2Regs.TBCTR = 0x0000;//清除计数器
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;//无活动加载
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;//同步直通

//
//将影子寄存器加载设置为零
//
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//
//设置比较值
//
EPwm2Regs.CMPA.bit.CMPA = Duty_SW[1];//设置比较 A 值
EPwm2Regs.CMPB.bit.CMPB = Duty_SW[1];//设置比较 B 值

//
//设置操作
//
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;//在递增计数期间设置事件 A 上的 Pwm2A
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;//在递减计数期间清除事件 A 上的 Pwm2A

EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;//在递增计数期间清除事件 B 上的 Pwm2B
EPwm2Regs.AQCTLB.bit.CBD = AQ_SET;//在递减计数期间设置事件 B 上的 Pwm2B

//
//高电平有效互补 PWM -设置死区
//
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;//完全启用:同时启用 A 和 B
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm2Regs.DBRED.bit.DBRED = N_three 相位死区;//上升沿高互补
EPwm2Regs.DBFED.bit.DBFED = N_three 相位死区;//下降沿高互补


//
// InitEPwm3 -初始化 EPWM3配置
//
空 InitEPwm3 (空)

//
//设置 TBCLK
//
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上/向下计数
EPwm3Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;//从机模式
EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;//相位为0
EPwm3Regs.TBCTR = 0x0000;//清除计数器
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;//无活动加载
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;//同步直通

//
//将影子寄存器加载设置为零
//
EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//
//设置比较值
//
EPwm3Regs.CMPA.bit.CMPA = Duty_SW[2];//设置比较 A 值
EPwm3Regs.CMPB.bit.CMPB = Duty_SW[2];//设置比较 B 值

//
//设置操作
//
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;//在递增计数期间设置事件 A 上的 PWM3A
EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;//在递减计数期间清除事件 A 上的 PWM3A

EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;//在递增计数期间清除事件 B 上的 PWM3B
EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;//在递减计数期间在事件 B 上设置 PWM3B

//
//高电平有效互补 PWM -设置死区
//
EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;//完全启用:同时启用 A 和 B
EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm3Regs.DBRED.bit.DBRED = N_three 相位死区;//上升沿高互补
EPwm3Regs.DBFED.bit.DBFED = N_three 相位死区;//下降沿高互补


//
// InitEPwm4 -初始化 EPWM4配置
//
空 InitEPwm4 (空)

//
//设置 TBCLK
//
EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//向上计数
EPwm4Regs.TBPRD = N_H_BRIDGE_SW_PERIOD;//设置计时器周期
EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;//主模式
EPwm4Regs.TBPHS.bit.TBPHS = 0x0000;//相位为0
EPwm4Regs.TBCTR = 0x0000;//清除计数器
EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW;//无活动加载
EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;//同步下行数据流

//
//将影子寄存器加载设置为零
//
EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//
//设置比较值
//
EPwm4Regs.CMPA.bit.CMPA = N_H_BRIDGE_SW_PERIOD / 2;//设置比较 A 值
EPwm4Regs.CMPB.bit.CMPB = N_H_BRIDGE_SW_PERIOD / 2;//设置比较 B 值

//
//设置操作
//
EPwm4Regs.AQCTLA.bit.CAU = AQ_SET;//在递增计数期间设置事件 A 上的 Pwm4A
EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR;//在递减计数期间清除事件 A 上的 Pwm4A

EPwm4Regs.AQCTLB.bit.CBU = AQ_CLEAR;//在递增计数期间清除事件 B 上的 Pwm4B
EPwm4Regs.AQCTLB.bit.CBD = AQ_SET;//在递减计数期间设置事件 B 上的 Pwm4B

//
//高电平有效互补 PWM -设置死区
//
EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;//完全启用:同时启用 A 和 B
EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm4Regs.DBRED.bit.DBRED = N_H_BRIDGE_DEADBAND;//上升沿高电平互补
EPwm4Regs.DBFED.bit.DBFED = N_H_BRIDGE_D死 区;//下降沿高互补


//
// InitEPwm5 -初始化 EPWM5配置
//
空 InitEPwm5 (空)

//
//设置 TBCLK
//
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//向上计数
EPwm5Regs.TBPRD = N_H_BRIDGE_SW_PERIOD;//设置计时器周期
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;//从机模式
EPwm5Regs.TBPHS.bit.TBPHS = N_H_BRIDGE_DUTY;//相移
EPwm5Regs.TBCTR = 0x0000;//清除计数器
EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW;//无活动加载
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;//同步直通

//
//将影子寄存器加载设置为零
//
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//
//设置比较值
//
EPwm5Regs.CMPA.bit.CMPA = N_H_BRIDGE_SW_PERIOD / 2;//设置比较 A 值
EPwm5Regs.CMPB.bit.CMPB = N_H_BRIDGE_SW_PERIOD / 2;//设置比较 B 值

//
//设置操作
//
EPwm5Regs.AQCTLA.bit.CAU = AQ_SET;//在递增计数期间设置事件 A 上的 Pwm5A
EPwm5Regs.AQCTLA.bit.CAD = AQ_CLEAR;//在递减计数期间清除事件 A 上的 Pwm5A

EPwm5Regs.AQCTLB.bit.CBU = AQ_CLEAR;//在递增计数期间清除事件 B 上的 Pwm5B
EPwm5Regs.AQCTLB.bit.CBD = AQ_SET;//在递减计数期间设置事件 B 上的 Pwm5B

//
//高电平有效互补 PWM -设置死区
//
EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;//完全启用:同时启用 A 和 B
EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm5Regs.DBRED.bit.DBRED = N_H_BRIDGE_DEADAND;//上升沿高电平互补
EPwm5Regs.DBFED.bit.DBFED = N_H_BRIDGE_D死 区;//下降沿高互补


//
// epwm1_ISR - EPWM1 ISR
//
_interrupt void epwm1_ISR (void)

//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

//电压矢量计算
CurrentController();

//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

//三相 PWM 计算
开关(PWM_Algorithm)

案例1:
SinePWM ();
中断;
案例2:
SinePWMTriangularInjection();
中断;
案例3:
SVPWM();
中断;

//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

//三相 PWM 寄存器更新
n_three 相位 SW_period = round (100e6 / f_sw_three 相位/ 4);

EPwm1Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期
EPwm2Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期
EPwm3Regs.TBPRD = N_th3_PHASE_SW_PERIOD;//设置计时器周期

EPwm1Regs.CMPA.bit.CMPA = ROUND (Duty_SW[0]* N_three PHASE_SW_PERIOD);//设置比较 EPWM1 A 值
EPwm2Regs.CMPA.bit.CMPA = ROUND (Duty_SW[1]* N_three PHASE_SW_PERIOD);//设置比较 EPWM2 A 值
EPwm3Regs.CMPA.bit.CMPA = ROUND (Duty_SW[2]* N_three PHASE_SW_PERIOD);//设置比较 EPWM3 A 值

//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

// H 桥 PWM 寄存器更新
n_H_BRIDGE_SW_PERIOD = ROUND (100e6 / f_SW_H_BRIDGE / 2);
n_H_BRIDGE_Duty = round (Duty_H_BRIDGE * N_H_BRIDGE_SW_PERIOD);

EPwm4Regs.TBPRD = N_H_BRIDGE_SW_PERIOD;//设置计时器周期
EPwm5Regs.TBPRD = N_H_BRIDGE_SW_PERIOD;//设置计时器周期

EPwm4Regs.CMPA.bit.CMPA = ROUND (N_H_BRIDE_SW_PERIOD / 2);//设置比较 EPWM4 A 值
EPwm5Regs.CMPA.bit.CMPA = ROUND (N_H_BRIDE_SW_PERIOD / 2);//设置比较 EPWM5 A 值

EPwm5Regs.TBPHS.bit.TBPHS = N_H_BRIDGE_DUTY;//相移

//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
//清除此计时器的 INT 标志
EPwm1Regs.ETCLR.bit.INT = 1;
//确认此中断以接收来自组3的更多中断
PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;


void CurrentController (void)

U_ref_amp = u_dc / sqrt_3 * m_a;
n_th3_PHASE_UPDATE = EPwm1Regs.ETPS.bit.INTPRD;
U_ref_angle = u_ref_angle + two_pi*f_f_f_f_f_sw_three 相位* n_three 相位更新;

if (u_ref_angle > two_pi)

U_ref_angle = u_ref_angle - two_pi;

U_ref_alpha = u_ref_amp * cos (u_ref_angle);
u_ref_beta = u_ref_amp * sin (u_ref_angle);

void SinePWM (void)

Duty_sw[0]= u_ref_alpha;
Duty_sw[1]=- u_ref_alpha / 2 + sqrt_3 * u_ref_beta / 2;
Duty_sw[2]=- u_ref_alpha / 2 - sqrt_3 * u_ref_beta / 2;

Duty_sw[0]= Duty_sw[0]* sqrT_3 / u_dc / 2 + 0.5;
Duty_sw[1]= Duty_sw[1]* sqrT_3 / u_dc / 2 + 0.5;
Duty_sw[2]= Duty_sw[2]* sqrT_3 / u_dc / 2 + 0.5;

void SinePWMTriangularInjection (void)(void)

Duty_sw[0]= u_ref_alpha;
Duty_sw[1]=- u_ref_alpha / 2 + sqrt_3 * u_ref_beta / 2;
Duty_sw[2]=- u_ref_alpha / 2 - sqrt_3 * u_ref_beta / 2;

U_ref_abc_max = Duty_sw[0];
U_ref_abc_min = Duty_sw[0];

for (i=1;i<=2;i++)

if (u_ref_abc_max < duty_sw[i])

U_ref_abc_max = Duty_sw[i];

if (u_ref_abc_min > Duty_sw[i])

U_ref_abc_min = Duty_sw[i];

U_try_ref =(u_ref_abc_max + u_ref_abc_min)/ 2;

Duty_sw[0]=(Duty_sw[0]- u_try_ref)* sqrT_3 / u_dc / 2 + 0.5;
Duty_sw[1]=(Duty_sw[1]- u_try_ref)* sqrT_3 / u_dc / 2 + 0.5;
Duty_sw[2]=(Duty_sw[2]- u_try_ref)* sqrT_3 / u_dc / 2 + 0.5;

//
void SVPWM (void)

//注意:u_ref 是一个非振幅空间矢量。

//每个单位系统
//三相多级 SVPWM 输出电压
//从-(N_level-1)/2*u_dc 到(N_level-1)/2*u_dc,
//完全(N_level-1)*u_dc。
//因此,电压基准应为(N_level-1)*u_dc/sqrt (3)

U_ref_amp_SVPWM = sqrt (u_ref_alpha* u_ref_alpha + u_ref_beta* u_ref_beta);//幅度
U_ref_ang_SVPWM = atan2 (u_ref_beta、u_ref_alpha);//角度

//扇区检测与旋转或翻转到扇区1
switch ((int16) floor (u_ref_ang_SVPWM*3/PI))

//扇区1:[0,PI/3)
情况0:
Sector_SVPWM = 1;
中断;

//扇区2:[PI/3,PI*2/3):翻转
案例1:
Sector_SVPWM = 2;
U_ref_ang_SVPWM = two_pi_over_three - u_ref_ang_SVPWM;
中断;

//扇区3:[PI*2/3,PI ):旋转
案例2:
Sector_SVPWM = 3;
U_ref_ang_SVPWM -= two_pi_over_three;
中断;

//扇区4:[-PI、-PI*2/3)& PI:翻转
案例-3:
案例3:
Sector_SVPWM = 4;
U_ref_ang_SVPWM =- two_pi_over_three - u_ref_ang_SVPWM;
中断;

//扇区5:[-pi*2/3,pi/3)& pi:旋转
情况-2:
Sector_SVPWM = 5;
U_ref_ang_SVPWM += 2_pi_over_three;
中断;

//扇区6:[-pi/3,0):翻转
情况-1:
Sector_SVPWM = 6;
U_ref_ang_SVPWM =- u_ref_ang_SVPWM;

//电压基准过高:将过调制转换为线性调制
if (u_ref_amp_SVPWM * sqrt_3 / u_dc > 1)
U_ref_amp_SVPWM = sqrt_3 / 2;
其他
U_ref_amp_SVPWM = 3 * u_ref_amp_SVPWM / 2 / u_dc;

// 60度坐标系
U_ref_alpha_SVPWM = u_ref_amp_SVPWM * cos (u_ref_ang_SVPWM);
U_ref_beta_SVPWM = u_ref_amp_SVPWM * sin (u_ref_ang_SVPWM);

//
Duty_SVPWM[1]= u_ref_alpha_SVPWM - u_ref_beta_SVPWM / sqrt_3;
Duty_SVPWM[2]= u_ref_beta_SVPWM * 2 / sqrt_3;
Duty_SVPWM[0]=(1 - Duty_SVPWM[1]- Duty_SVPWM[2])/2;

// Vector_A * Duty_cycle_Vector_A + Vector_B * Duty_cycle_Vector_B + Vector_1_1 * Duty_cycle_Vector_1_1_1
Duty_SW[0]= V_SVPWM_BASIC [扇区_SVPWM][0][0]* Duty_SVPWM[1]+ V_SVPWM_BASIC [扇区_SVPWM][1][0]* Duty_SVPWM[2]+ Duty_SVPWM[0];
Duty_SW[1]= V_SVPWM_BASIC [扇区_SVPWM][0][1]* Duty_SVPWM[1]+ V_SVPWM_BASIC [扇区_SVPWM][1]* Duty_SVPWM[2]+ Duty_SVPWM[0];
Duty_SW[2]= V_SVPWM_BASIC [扇区_SVPWM][0][2]* Duty_SVPWM[1]+ V_SVPWM_BASIC [扇区_SVPWM][1][2]* Duty_SVPWM[2]+ Duty_SVPWM[0];


//
//文件结束
//

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我写信告诉您、C2000团队成员已被分配到此帖子、应该很快回答。

    此致
    Baskaran
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    唐俊飞、您好!

    以下是我对您每一个问题的回答:

    1)对于1)、您必须确保 PWM 时钟不大于100MHz。 您可以将时钟编程为200MHz、但此设置无效、因为无法保证设计超过100MHz。

    对于 TBPRD 计算、请记住您处于上-下计数模式(EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_updown)

    这意味着时基计数器将向上计数到周期、每次向下计数到0、因此 TBPRD 应该是向上计数模式的一半。

    ------

    2) 2)我的第一个想法是、听起来 ISR 没有及时执行。 您能否尝试在 ISR 的开始和退出时切换 GPIO、并将其与 PWM 输出进行比较?

    ------

    3)您能否提供有关此内容的更多详细信息? 当您说 PWM "始终提供0V 电压"或"始终提供3.3V 电压"时、是在编程之前还是 PWM 根本不工作? 您使用什么硬件进行开发?

    此致、
    Kris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kris、

    (一)我已将数值乘以两次来考虑递增和递减计数:

    100 [MHz]/ 25 [kHz]/ 2 = 2000

    但是、实际上我发现我需要再次将其除以2、即 TBPRD 应设置为1000、以获得25kHz 的开关频率。 这种"再除以2 "对我来说是令人困惑的。

    (2) I SET

    EPwm1Regs.ETPS.bit.INTPRD = et_1st

    然后在 ISR 开始时切换 GPIO10:

    如果(k = 0)

      GPIO_WritePin (10、1);
      K = 1;

    其他

      GPIO_WritePin (10、0);
      K = 0;

    这就是我得到的结果:

    完成一个 ISR 需要超过100us、这意味着它需要超过

    100 [us]* 100 [MHz]= 10000 SYSCLK

    完成一个 ISR。 这是不可思议的、因为我的 ISR 根本不复杂、只需一个 PWM 占空比计算代码(我使用开关从三个 PWM 算法中选择一个)。  

    我还在 ISR 函数的开头设置了一个断点、并在 CPU 遇到断点时绘制计数器值。 ISR 似乎从计数器值的任意点开始、而不是 EPwm1Regs.TBCTR = 0。

    是否有任何解释和解决方案?

    (3)我只需将 H 桥 PWM 引脚连接到示波器。 我的意思  是 EPWM4A 和5A 始终提供逻辑高电平、而 EPWM4B 和5B 始终提供逻辑低电平。

    我 通过将比较值设置为周期的一半、将 EPWM4的占空比和代码中的5设置为50%:

    EPwm4Regs.TBPRD     = N_H_BRIDGE_SW_PERIOD;    //设置计时器周期

    EPwm4Regs.CMPA.bit.CMPA = N_H_BRIDGE_SW_PERIOD / 2;  //设置比较 A 值

    EPwm4Regs.CMPB.bit.CMPB = N_H_BRIDGE_SW_PERIOD / 2;  //设置比较 B 值

    我认为 EPWM 功能是通过某种方式激活的、否则所有 EPWM4A、4B 5A 和5B 都应归零。 但是、它们配置不正确。  

    我按照 "TMS320x280x 增强型脉宽调制器(ePWM)模块参考指南(SPRU791)"中的示例代码进行了编程。 这可能仅对 TMS320x280x 有效、但不适用于 TMS320F28379D?

    非常感谢、期待您的帮助!

    此致、

    邓俊飞

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    唐俊飞

    1)是否可以验证 TBCLKDIV 和 HSPCLKDIV 都设置为1分频? 对于需要在较低频率下操作 PWM 的用户、可以选择进一步对 TBCLK 进行分频。

    2) 2)您能否稍微修改此设置以在 ISR 开始和结束时切换 GPIO? 如果我理解正确、您将在每个 ISR 开始时进行切换、因此您将等待一个完整的 PWM 周期、直至发生下一个事件。 应该是这样

    my_isr ()

    SET_GPIO;

    … // ISR 代码
    (笑声)
    CLEAR_GPIO;


    3)是否可以检查 EPWM4A 和5A 引脚上的上拉电阻器? 这将位于 GpioCtrlRegs GPxPUD 寄存器中。

    此致、
    Kris

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kris、

     

    (1)以下是我的设置:

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

    EPwm1Regs.TBCTL.bit.CLKDIV  = TB_DIV1;

    我想这意味着这两个值都被1除、对吧?

     

    (2)我修改了切换代码、这里是更新的图:


    似乎94.651%的 CPU 时间在 ISR 函数中。

     

    (3)在代码开头初始化 EPWM1-5:

    InitEPwm1Gpio();
    InitEPwm2Gpio();
    InitEPwm3Gpio();
    InitEPwm4Gpio();
    InitEPwm5Gpio();

    例如 ,在 InitEPwm1Gpio()中,它包括:

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1; //禁用 GPIO0上的上拉电阻(EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; //禁用 GPIO1上的上拉电阻(EPWM1B)
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;//将 GPIO0配置为 EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1=1;//将 GPIO1配置为 EPWM1B

    是否应该为 ePWM 输出禁用上拉电阻? 在 InitEPwmxGpio()中、所有 EPWM1-5的配置都是相同的、我认为由于 EPWM1-3上拉电阻器被禁用并提供 PWM 输出、 EPWM4-5还应提供 PWM 输出、 对吧?

     

    非常感谢!

    此致、

    邓俊飞

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    唐俊飞

    您能否发布 ISR 的内容? 根据您告诉我们的内容、似乎不应该花费这么长的时间。  编辑:我正在寻找具有 GPIO 切换的更新 ISR。 我假设自原始帖子以来、代码的其余部分没有变化。

    至于上拉电阻、如果引脚正确设置为 ePWM 引脚、则它们将过驱动上拉电阻、不应产生任何影响。 对于此问题、需要验证以下几点:

    • 确保启用 ePWM 时钟(PCLKCRx)
    • 确保时基正在计数。 将 TBCTR 添加到 CCS 中的"Expressions"窗口中、然后运行/停止处理器。 确保值正在更改。
    • 在"Expressions"窗口中检查 GPIO 寄存器。 具体而言、确保引脚的 GPxMUX 寄存器配置正确。
    • 如果所有这些看起来都正确、请检查 ePWM 中的 TZFLG 寄存器以确保没有发生跳闸事件。

    此致、

    Kris

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kris、

    (1)时钟计算没有问题?

    (2)我的 ISR 在这里:

    //
    // epwm1_ISR - EPWM1 ISR
    //
    __interrupt void epwm1_ISR (void)
    { 
    GPIO_WritePin (10、1); //=================================================================== //电压矢量计算 电流控制器(); //=================================================================================================================================================================================================================== //三相 PWM 计算 开关(PWM_Algorithm) { 案例1: SinePWM (); break; 案例2: SinePWMTriangularInjection (); break; 案例3: SVPWM (); break; }//=================================================================================================================================================== //三相 PWM 寄存器更新 N_th3_PHASE_SW_PERIOD= round (100e6 / f_SW_three 相位/ 4); EPwm1Regs.TBPRD= N_th3_PHASE_SW_PERIOD;//设置计时器周期 EPwm2Regs.TBPRD= N_th3_PHASE_SW_PHASE_SW_PERIOD;//设置 EPwm1SW_SECTOR_SECTOR_SECTOR.SW_SECTOR_SECTOR.N = EPmSW_SECTOR_SECTOR.EN.SW_SECTOR_SECTOR_SECTOR.N = EPmSW_SECTOR_SECTOR_SECTOR.N = EPmSW_SECTOR.EN.SW_SECTOR_SECTOR_SECTOR.N = EP3个 EPmSW_SECTOR_SECTOR.SW_SECTOR.SW_SECTOR.EN.EN.EN.SW_SECTOR_SECTOR_SEC//设置比较 EPWM2值 EPwm3Regs.CMPA.bit.CMPA= round (Duty_SW[2]* N_three PHASE_SW_PERIOD);//设置比较 EPWM3 a 值 //================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== // H 桥 PWM 寄存器更新 N_H_BRIDGE_SW_PERIOD= round (100e6 / f_SW_H_BRIDGE / 2); N_H_BRIDGE_DUTY= round (Duty_H_BRIDGE_SW_PERIOD); EPwm4Regs.TBPRD= N_H_BRIDGE_SW_PERIOD = N_PWM2/ EPmBRIDGE.SW_CH_SW_CH_SECTOR/EP4SW_CH_CH_REGISE.N = EP4SW_SECTOR.SW_CH_CH_ROUND;EP_SW_CH_SW_CH_REGISTSW_REGER.SW_SW_CH_SECR = EP4SW_CH_CH_REGISE.N = EP4SW_SW_CH_CH_REGIST.SW_SECR = EP4SW_SECR = EP4SW //设置比较 EPWM5 A 值 EPwm5Regs.TBPHS.bit.TBPHS= N_H_BRIDGE_DUTY;//相移//=========================================================================================================================================================================================================================================================================================================================================== //清除此计时器的 INT 标志 EPwm1Regs.ETCLR.bit.INT = 1; //确认此中断以接收来自组3的更多中断 PieCtrlRegs.PIEACX.ALL = PIEACK_Group3; GPIO_WritePin (10、0); }

     CurrentController()、 SinePWM ()、 SinePWMTriangularInjection ()和 SVPWM ()与以前一样。

    (3)

    • 寄存器被置位:

    CpuSysRegs.PCLKCR2.bit.EPWM4= 1;

    CpuSysRegs.PCLKCR2.bit.EPWM5=1;

    • 我应用了"连续刷新"、可以看到 EPWM4和 EPWM5都在计数。
    • GPIO0-GPIO9的多路复用器设置为1。
    • TZFLG 全部为零。

    检测到另外一个问题:EPWM1、2和3应该同步、但现在 EPWM1、2和3的 TBCTL 不一样、这意味着它们不 同步、对吧? 此外  、EPWM4和5的 TBCTL 应移位250、但情况似乎并非如此、这对我来说也是令人困惑的。

    从我的代码中可以看到、我使用这些设置使它们同步:

    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    //主模式

    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;     //从模式

    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;     //从模式

    EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;    //主模式

    EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;     //从模式

     

    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;  //同步下行数据流

    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  //同步直通

    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  //同步直通

    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;  //同步下行数据流

    EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  //同步直通

     

    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;       //相位为0

    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;       //相位为0

    EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;       //相位为0

    EPwm4Regs.TBPHS.bit.TBPHS = 0x0000;       //相位为0

    EPwm5Regs.TBPHS.bit.TBPHS = N_H_BRIDGE_DUTY;  //相移250

    出什么问题了吗?

    此致、

    邓俊飞

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好

    我对你的第二个问题也有类似的问题。
    我已经尝试创建一些代码来生成空间矢量调制、但与您的情况类似、执行时间似乎有问题。

    我很想了解您的代码有什么问题!