Hi,
I have a problem with Piccolo Controller. I'm using PWM Modules with PWM1 as master and Pwm2,3,4 as slaves. I
need to control two H-Bridges with Phase shift and I'm using a High-res PWM in UP-DOWN configuration. The modulation control is done by using a fixed value for CMPA register
for all modules and changing the TBPHS register value in modules PWM2,3,4.
In this situation, when the CMPA value falls between the previous and next TBPHS register values ( Phase is 50% ), I lose some CMP Events.
The PWM configuration is as follows:
EPwm1Regs.TBPRD = uintPeriodAtt; // PWM Period: xx us to 60 MHz CPU clock
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0 (inital condition )
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = (Uint16)(uintPeriodAtt / 2 ); // Set compare A value
EPwm1Regs.CMPA.half.CMPAHR = 0; // Set high resolution compare A value
EPwm1Regs.CMPB = 0 ; // Set Compare B value
// Setup counter mode
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module: disable phase loading
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Active Period Register Load From Shadow Register Select
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;
// Setup shadowing
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // Load on Zero or period
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // Load on Zero or period
// Set actions
// settings for PWM active High
EPwm1Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // No Action PWM1A on event ZERO count
EPwm1Regs.AQCTLA.bit.PRD = AQ_NO_ACTION; // No Action PWM1A on event PERIOD count
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.AQCTLA.bit.CBU = AQ_NO_ACTION; // No Action PWM1A on event B, up count
EPwm1Regs.AQCTLA.bit.CBD = AQ_NO_ACTION; // No Action PWM1A on event B, down count
EPwm1Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // No Action PWM1B on event ZERO count
EPwm1Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // No Action PWM1B on event PERIOD count
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Clear PWM1B on event A, up count
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // Set PWM1B on event A, down count
EPwm1Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // No Action PWM1B on event B, up count
EPwm1Regs.AQCTLB.bit.CBD = AQ_NO_ACTION; // No Action PWM1B on event B, down count
//DEAD TIME
EPwm1Regs.DBCTL.bit.IN_MODE = 0 ;
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC;
EPwm1Regs.DBFED = (Uint16)DeadTimeTmp; /value of Dead Time
EPwm1Regs.DBRED = (Uint16)DeadTimeTmp;
// Enable High Resolution ePWM on ePWM1 module
EPwm1Regs.HRCNFG.all = 0; // Clear all bits first
EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP; // Enable the high precision position control on the falling edge
EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // Load the CMPAHR registre on either CTR=Zero or CTR=PRD
EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable Auto-conversion
EPwm1Regs.HRCNFG.bit.SELOUTB = 0; // ePWMxB output is inverted version of ePWMxA signal
EPwm1Regs.HRPCTL.bit.HRPE = 1 ; // Turn on high-resolution period control.
// Interrupt where we will change the Compare Values
// The interrupt generate the SOCA for ADC module
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Enable INT on 1st event
EPwm1Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate ADC start of conversion A event on 1st event
EPwm1Regs.ETPS.bit.SOCBPRD = ET_DISABLE; // Disable the SOCB event counter.
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // SOCA event time-base counter = ZERO
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // Select INT on PRD event
EPwm2Regs.TBPRD = uintPeriodAtt - 1 ; // PWM Period: xx us to 60 MHz CPU clock
EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm2Regs.TBCTR = 0x0000; // Clear counter
// Set Compare values
EPwm2Regs.CMPA.half.CMPA = ((Uint16)uintPeriodAtt / 2 ); // Set compare A value
EPwm2Regs.CMPA.half.CMPAHR = 0; // Set high resolution compare A value
EPwm2Regs.CMPB = 0;
// Setup counter mode
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Master module: disable phase loading
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Active Period Register Load From Shadow Register Select
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down-stream module
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.FREE_SOFT = 11;
// Setup shadowing
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // Load on Zero or period
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
// Set actions
// settings for PWM active High
EPwm2Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // No Action PWM2A on event ZERO count
EPwm2Regs.AQCTLA.bit.PRD = AQ_NO_ACTION; // No Action PWM2A on event PERIOD count
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM2A on event A, down count
EPwm2Regs.AQCTLA.bit.CBU = AQ_NO_ACTION; // No Action PWM2A on event B, up count
EPwm2Regs.AQCTLA.bit.CBD = AQ_NO_ACTION; // No Action PWM2A on event B, down count
EPwm2Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // No Action PWM2B on event ZERO count
EPwm2Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // No Action PWM2B on event PERIOD count
EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Clear PWM2B on event A, up count
EPwm2Regs.AQCTLB.bit.CAD = AQ_SET; // Set PWM2B on event A, down count
EPwm2Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // No Action PWM2B on event B, up count
EPwm2Regs.AQCTLB.bit.CBD = AQ_NO_ACTION; // No Action PWM2B on event B, down count
//Dead Time
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC;
EPwm2Regs.DBFED = (Uint16)DeadTimeTmp;
EPwm2Regs.DBRED = (Uint16)DeadTimeTmp;
// Enable High Resolution ePWM on ePWM1 module
EPwm2Regs.HRCNFG.all = 0; // Clear all bits first
EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP; // Enable the high precision position control on the falling edge
EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // Load the CMPAHR registre on either CTR=Zero or CTR=PRD
EPwm2Regs.HRCNFG.bit.AUTOCONV = 1; // Enable Auto-conversion
EPwm2Regs.HRCNFG.bit.SELOUTB = 0; // ePWMxB output is inverted version of ePWMxA signal
EPwm2Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.
// Interrupt where we will change the Compare Values
// The interrupt generate the SOCA for ADC module
EPwm2Regs.ETPS.bit.INTPRD = ET_DISABLE; // Disable INT
EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate ADC start of conversion A event on 1st event
EPwm2Regs.ETPS.bit.SOCBPRD = ET_DISABLE; // Disable the SOCB event counter.
EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // SOCA event time-base counter = 0
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event - centro del comando