Other Parts Discussed in Thread: TXB0106
Hi
We're going to use 0.5-1MHz 4phase h-bridge, deadband, high resolution involved. Looks like DB generator is heavily broken. In some conditions on some PWM outputs I see strong and fat >2V spikes. See attached oscillogram and compilable code. Standalone Launchpad board, nothing else connected. On oscillogram From top to bottom:
GPIO12 (Launchpad pin 39, PWM7B)
GPIO13 (Launchpad pin 40, PWM7A)
GPIO14 (Launchpad pin 37, PWM8B)
GPIO14 (Launchpad pin 38, PWM8A)
What's wrong with my code? How to fix it reliably?
Thanks
Edward
Better grounding but two channels. Spike pulse width is about 10ns:
#include "F28x_Project.h"
#define PHB1REGS EPwm7Regs
#define PHB2REGS EPwm8Regs
#define CPU_SYS_CLOCK 200000ul // kHz
// assuming default 1/2 divider in PERCLKDIVSEL.EPWMCLKDIV
#define EPWM_CLOCK (CPU_SYS_CLOCK /2u) // kHz , 100MHz max
#define PWM_FREQ 1000u //kHz
#define PWM_MAX (EPWM_CLOCK / PWM_FREQ)
#define ADC_PWM_DIV 2
#define INIPHOFFSET 5
void SetPwmPhb_F(float f)
{
unsigned int q;
unsigned long Q;
f = f * (float)PWM_MAX;
q = f;
Q = ((unsigned long)q << 16);
PHB1REGS.CMPA.all = Q; // linked to PHB2 as well
}
void SetPwmPhbDT(void)
{
float dt;
unsigned int q;
dt = 1500 * 0.02;
q = dt;
PHB1REGS.DBRED.bit.DBRED = q;
PHB2REGS.DBRED.bit.DBRED = q;
PHB1REGS.DBFED.bit.DBFED = q;
PHB2REGS.DBFED.bit.DBFED = q;
}
static void InitPWM7(void)
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; // Disable pull-up on GPIO12 (EPWM7A)
GpioCtrlRegs.GPAPUD.bit.GPIO13 = 1; // Disable pull-up on GPIO13 (EPWM7B)
GpioCtrlRegs.GPAGMUX1.bit.GPIO12 = 0; // Configure GPIO2 as EPWM7A
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 1; // Configure GPIO2 as EPWM7A
GpioCtrlRegs.GPAGMUX1.bit.GPIO13 = 0; // Configure GPIO3 as EPWM7B
GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 1; // Configure GPIO3 as EPWM7B
EPwm7Regs.TBCTL.bit.CTRMODE = TB_FREEZE; // Count up
EPwm7Regs.TBCTL.bit.FREE_SOFT = 2; // free run
EPwm7Regs.TBCTR = 0x0000+INIPHOFFSET; // initial ctr
EPwm7Regs.TBPRD = (EPWM_CLOCK / PWM_FREQ)-1; // Set timer period
EPwm7Regs.TBPHS.all = 0x0000; // Phase is 0
//
// Setup TBCLK
//
EPwm7Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm7Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm7Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow just to observe on
// the scope
EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
// Setup compare
//
EPwm7Regs.CMPA.bit.CMPA = 0;
//
// Set actions
//
EPwm7Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm7Regs.AQCTLA.bit.ZRO = AQ_SET;
//EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; // optional
//EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // optional
//
// Active Low complementary PWMs - setup the deadband
//
EPwm7Regs.DBCTL.bit.HALFCYCLE = 1;
EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm7Regs.DBCTL.bit.IN_MODE = DBA_ALL;
//EPwm2Regs.DBRED.bit.DBRED = 4;
//EPwm2Regs.DBREDHR.bit.DBREDHR = 100;
//EPwm2Regs.DBFED.bit.DBFED = 4;
//EPwm2Regs.DBFEDHR.bit.DBFEDHR = 100;
// SOCA pulse to ADC
EPwm7Regs.ETPS.bit.SOCAPRD = ADC_PWM_DIV;
EPwm7Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm7Regs.ETSEL.bit.SOCAEN = 1;
//
// Interrupt where we will modify the deadband
//
// EPwm7Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
// EPwm7Regs.ETSEL.bit.INTEN = 1; // Enable INT
// EPwm7Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
EPwm7Regs.HRCNFG.all = 0x0;
EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
//EPwm7Regs.HRCNFG.bit.AUTOCONV = 1;
//EPwm7Regs.HRMSTEP.all = 0xFFFF;
EPwm7Regs.TZSEL.bit.CBC6 = 1; // on CPU stop
EPwm7Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm7Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;
EDIS;
}
static void InitPWM8(void)
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO14 = 1; // Disable pull-up on GPIO12 (EPWM7A)
GpioCtrlRegs.GPAPUD.bit.GPIO15 = 1; // Disable pull-up on GPIO13 (EPWM7B)
GpioCtrlRegs.GPAGMUX1.bit.GPIO14 = 0; // Configure GPIO2 as EPWM7A
GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 1; // Configure GPIO2 as EPWM7A
GpioCtrlRegs.GPAGMUX1.bit.GPIO15 = 0; // Configure GPIO3 as EPWM7B
GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 1; // Configure GPIO3 as EPWM7B
EPwm8Regs.TBCTL.bit.CTRMODE = TB_FREEZE; // Count up
EPwm8Regs.TBCTL.bit.FREE_SOFT = 2; // free run
EPwm8Regs.TBCTR = EPWM_CLOCK / PWM_FREQ / 2 -1+INIPHOFFSET;
EPwm8Regs.TBPRD = (EPWM_CLOCK / PWM_FREQ)-1; // Set timer period
EPwm8Regs.TBPHS.all = 0x0000; // Phase is 0
//
// Setup TBCLK
//
EPwm8Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm8Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm8Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm8Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm8Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow just to observe on
// the scope
EPwm8Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm8Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm8Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm8Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
// Setup compare
//
EPwm8Regs.CMPA.bit.CMPA = 0;
//
// Set actions
//
EPwm8Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm8Regs.AQCTLA.bit.ZRO = AQ_SET;
//EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; // optional
//EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // optional
//
// Active Low complementary PWMs - setup the deadband
//
EPwm8Regs.DBCTL.bit.HALFCYCLE = 1;
EPwm8Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm8Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm8Regs.DBCTL.bit.IN_MODE = DBA_ALL;
//EPwm2Regs.DBRED.bit.DBRED = 4;
//EPwm2Regs.DBREDHR.bit.DBREDHR = 100;
//EPwm2Regs.DBFED.bit.DBFED = 4;
//EPwm2Regs.DBFEDHR.bit.DBFEDHR = 100;
//
// Interrupt where we will modify the deadband
//
// EPwm7Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
// EPwm7Regs.ETSEL.bit.INTEN = 1; // Enable INT
// EPwm7Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
EPwm8Regs.HRCNFG.all = 0x0;
//EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;
//EPwm2Regs.HRMSTEP.all = 0xFFFF;
EPwm8Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm8Regs.EPWMXLINK.bit.CMPBLINK = 7-1;
EPwm8Regs.EPWMXLINK.bit.CMPALINK = 7-1;
EPwm8Regs.TZSEL.bit.CBC6 = 1; // on CPU stop
EPwm8Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm8Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;
EDIS;
}
void main(void)
{
EALLOW;
CpuSysRegs.PCLKCR2.all |= (1<< (7-1)) | (1<<(8-1));
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
InitPWM7();
InitPWM8();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
SetPwmPhbDT();
SetPwmPhb_F(0.7211);
for(;;)
{
}
}





