Tool/software: Code Composer Studio
Hello
I am having kind of a weird problem. I set up 3 ePWMs (1,2 and 3) and I want to control their duty cycle and their phase shift.
The duty cycle works perfectly and also the phase shift works up to some level but something weird happens when I increase the phase shift of the third channel above a number of 2300 (e.g. 2400 or something in that range, not exactly 2300). The signal in this case just dissapears ( I assume it becomes zero or so but nothing comes out of the PWM)
I would have the three signals to be 120° phase shifted. So for a TBPRD of 2000 in up-down mode, this becomes a phase shift of 2000*2*(1/3) and 2000*2*(2/3) but this does not work.
Below you can find my code, which is adapted from the epwm_updown_aq_cpu01 example, provided by TI.
Does anyone had a similar problem or any advice that you could give me?
Kind regards
//###########################################################################
// $TI Release: F2837xD Support Library v200 $
// $Release Date: Tue Jun 21 13:00:02 CDT 2016 $
// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h"
//
// Defines
//
#define EPWM1_TIMER_TBPRD 2000 // Period register
#define EPWM2_TIMER_TBPRD 2000 // Period register
#define EPWM3_TIMER_TBPRD 2000 // Period register
//
// Globals
//
typedef struct
{
volatile struct EPWM_REGS *EPwmRegHandle;
Uint16 EPwm_CMPA_Direction;
Uint16 EPwm_CMPB_Direction;
Uint16 EPwmTimerIntCount;
Uint16 EPwmMaxCMPA;
Uint16 EPwmMinCMPA;
Uint16 EPwmMaxCMPB;
Uint16 EPwmMinCMPB;
}EPWM_INFO;
EPWM_INFO epwm1_info; //Wat is dit juist voor iets????
EPWM_INFO epwm2_info;
EPWM_INFO epwm3_info;
double DELTA_1A = 10;
double DELTA_2A = 10;
double DELTA_3A = 10;
int SET_EPWM1_CMPA = 100;
int SET_EPWM2_CMPA = 100;
int SET_EPWM3_CMPA = 100;
int PHASE_1A = 0; //(int)(2000*0);
int PHASE_2A = 0; //667; //(int)(2000*(1/3));
int PHASE_3A = 0; //1334; //(int)(2000*(2/3));
//
// Function Prototypes
//
void InitEPwm1Example(void);
void InitEPwm2Example(void);
void InitEPwm3Example(void);
//
// Main
//
void main(void)
{
InitSysCtrl();
InitGpio();
PHASE_1A = 0; //(int)(2000*0);
PHASE_2A = 667;//0; //x7D0; //(int)(2000*2/3);
PHASE_3A = 3000; //xBB8;//3000;//(int)(2000*2*2/3);
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
DINT;
InitPieCtrl(); // De PIE -> alles wat met interrupts te maken heeft, moet in het begin gewoon geinitialiseerd worden
IER = 0x0000; // Interrupt Enable Register
IFR = 0x0000; //Interrupt Flag Register
InitPieVectTable();
EALLOW; // This is needed to write to EALLOW protected registers
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1Example();
InitEPwm2Example();
InitEPwm3Example();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
while(1) // endless loop - wait for an interrupt
{
SET_EPWM1_CMPA = (int)(((100-DELTA_1A)/100)*EPWM1_TIMER_TBPRD-1);
SET_EPWM2_CMPA = (int)(((100-DELTA_2A)/100)*EPWM2_TIMER_TBPRD-1);
SET_EPWM3_CMPA = (int)(((100-DELTA_3A)/100)*EPWM3_TIMER_TBPRD-1);
EPwm1Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA; // Set compare A value -OK
EPwm2Regs.CMPA.bit.CMPA = SET_EPWM2_CMPA; // Set compare A value -OK
EPwm3Regs.CMPA.bit.CMPA = SET_EPWM3_CMPA; // Set compare A value -OK
asm(" NOP");
}
}
//
// InitEPwm1Example - Initialize EPWM1 configuration
//
void InitEPwm1Example()
{
//
// Setup TBCLK
//
EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs - OK, exacte waarde nadien aanpassen
EPwm1Regs.TBPHS.bit.TBPHS = PHASE_1A; // Phase is 0 -OK
EPwm1Regs.TBCTR = 0x0000; // Clear counter -OK, gewoon op nul zetten
//
// Set Compare values
//
EPwm1Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA; // Set compare A value -OK
//EPwm1Regs.CMPB.bit.CMPB = EPWM1_MAX_CMPB; // Set Compare B value -OK
//
// Setup counter mode
//
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down - why isn't this equak to 01???
EPwm1Regs.TBCTL.bit.PHSEN = 0;//TB_DISABLE; // Disable phase loading -OK
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT -OK
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; //-OK
EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK
//
// Setup shadowing - Niet nodig voor ons
//
// EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
// EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
// EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
// EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
// Set actions
//
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up
// count
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A,
// down count
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up
// count
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B,
// down count
//
// Interrupt where we will change the Compare Values - momenteel niet nodig
//
//EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
//EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
//EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
//
}
//
// InitEPwm2Example - Initialize EPWM2 configuration
//
void InitEPwm2Example()
{
//
// Setup TBCLK
//
EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer period 801 TBCLKs
EPwm2Regs.TBPHS.bit.TBPHS = PHASE_2A; //0x0000; // Phase is 0
EPwm2Regs.TBCTR = 0x0000; // Clear counter
//
// Set Compare values
//
EPwm2Regs.CMPA.bit.CMPA = SET_EPWM2_CMPA; // Set compare A value
//EPwm2Regs.CMPB.bit.CMPB = EPWM2_MIN_CMPB; // Set Compare B value
//
// Setup counter mode
//
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
EPwm2Regs.TBCTL.bit.PHSEN = 1;//TB_DISABLE; // Disable phase loading
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK
//
// Setup shadowing
//
//EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
//EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
//EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
//EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
// Set actions
//
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up
// count
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM2A on event B, down
// count
EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Clear PWM2B on zero
EPwm2Regs.AQCTLB.bit.PRD = AQ_SET; // Set PWM2B on period
//
// Interrupt where we will change the Compare Values
//
//EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
//EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
//EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
}
//
// InitEPwm3Example - Initialize EPWM3 configuration
//
void InitEPwm3Example(void)
{
EPwm3Regs.TBPRD = EPWM3_TIMER_TBPRD; // Set timer period
//
// Setup TBCLK
//
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down and down
EPwm3Regs.TBCTL.bit.PHSEN = 1;//TB_DISABLE; // Disable phase loading
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm3Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK
EPwm3Regs.TBPHS.bit.TBPHS = PHASE_3A; //0x0000; // Phase is 0
EPwm3Regs.TBCTR = 0x0000; // Clear counter
//
// Setup shadow register load on ZERO
//
//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;
//
// Set Compare values
//
EPwm3Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA; // Set compare A value
//EPwm3Regs.CMPB.bit.CMPB = EPWM3_MAX_CMPB; // Set Compare B value
//
// Set Actions
//
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM3A on period
EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM3A on event B, down
// count
EPwm3Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Clear PWM3A on period
EPwm3Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM3A on event A, up
// count
}
//
// End of file
//