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.
Tool/software: Code Composer Studio
Hi TI Community,
i try here to shifting my two PWMs (ePWM1A and ePWM1B) with 180 degree, i used your example of epwm _synchronization, and i got a shift between two ePWMs for example ePWM1 and ePWM2. and now how cana i get a shift for ePWMA and ePWMB and not an inverted signal.
Thank you!
here is my initEPWM1:
void initEPWM1_Configuration(void)
{
EPWM_setClockPrescaler(EPWM1_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
//
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBaseCounter(EPWM1_BASE, 0);// count initial value setting
EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM_TIMER_TBPRD); //count cycle fs=300khz
//
EPWM_setPeriodLoadMode(EPWM1_BASE, EPWM_PERIOD_SHADOW_LOAD);// CYCLE LOADING MODE
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD); // comparison value loading mode
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, Duty_cycle); //Set the comparison value
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, Duty_cycle);
//
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); //ePWMA
//
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); //ePWMA
//
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
//
EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); //Synchronize pulse when counting to zero
//
EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(EPWM1_BASE, EPWM_DB_INPUT_EPWMA); //Configure dead zone input mode
EPWM_setDeadBandDelayPolarity(EPWM1_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_HIGH); // configuration polarity
EPWM_setDeadBandDelayMode(EPWM1_BASE,EPWM_DB_RED,true);
EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED, true); //Configure output mode
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE,EPWM_DB_OUTPUT_A,false);
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE, EPWM_DB_OUTPUT_B, false); //Output is not exchanged
//
EPWM_setRisingEdgeDelayCount(EPWM1_BASE, Dead_Band_RED); //Rising edge delay 0nS
EPWM_setFallingEdgeDelayCount(EPWM1_BASE, Dead_Band_FED); //falling edge delay 0nS
}
The C28x uses a modular PWM architecture; each module producing two PWM outputs (A and B) from the same time-base. The hardware phase shift mechanism allows the user to adjust the offset between time-bases of separate PWM modules. If you want to create phase shift between PWM patterns on A & B outputs on the same module, you will have to set up the Counter Compare (CC) and Acquisition Qualifier (AQ) sub-modules in your code to do this. It will be challenging in up-count mode, but in up-down count mode you could do something like in the attachment.
BTW, there is a video on PWM architecture which you may find helpful, here:
Regards,
Richard
Hi Richard,
i followed your tips, i still have difficulties to determine the duty-cycle for example 20%, the time-base period is 2000. the settings for SetAction are as right as below!
Thank you
// Set-up compare
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, 400U); // need Duty-cycle of 20%
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-400U)); // need Duty-cycle of 20%
// Set actions
/*EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);*/
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
/*EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_NO_CHANGE,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);*/
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
/* EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_NO_CHANGE,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);*/
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
Assuming you have configured the counter in up-down mode, as I draw this out I think you're going to get 30% duty on output A and 10% on output B. Is that right?
You have output A going high on an up-count match of 400, and low on an up-count of 1600, so 1200 counts on a time-base of 4000 (remember, up-down mode will double the number of clock pulses in a PWM period). 1200/4000*100 = 30%.
You have output B going high on a period event and low on down count match of 1600, so 400 counts. 400/4000*100 = 10%.
Start by drawing out the waveforms you want on the time-base, in a similar way to the .pdf I sent. That should guide you towards the right AQ settings.
What is the duty and phase relationship you're trying to get?
Regards,
Richard
Hi Richard,
I try to get a phase shift of 180 degrees between the two, both should have the same duty cycle for example from 10% to 50%.
with :
// Set-up compare
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, 400U); // need Duty-cycle of 20%
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-800U)); // need Duty-cycle of 20%
i got for example 20% but but not the exact phase shift
Regards
YT
Since you're looking for a fixed 180 deg phase, this should be easy. What about something like this?
// Set-up compare
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, 800U); // need Duty-cycle of 20%
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-800U)); // need Duty-cycle of 20%
// Set actions
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(base,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
Hope this helps.
Regards,
Richard
Hi Richard,
i have another question, it's about the Dead Band settings, i have added the Dead Band setting to the upper code, but i don't get any phase shift anymore, i've tried to solve with the more times, you might have a solution ? Thank you
Best Regards
YT
EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); //Synchronize pulse when counting to zero
//
EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(EPWM1_BASE, EPWM_DB_INPUT_EPWMA); //Configure dead zone input mode
EPWM_setDeadBandDelayPolarity(EPWM1_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_HIGH); // configuration polarity
EPWM_setDeadBandDelayMode(EPWM1_BASE,EPWM_DB_RED,true);
EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED, true); //Configure output mode
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE,EPWM_DB_OUTPUT_A,false);
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE, EPWM_DB_OUTPUT_B, false); //Output is not exchanged
//
EPWM_setRisingEdgeDelayCount(EPWM1_BASE, Dead_Band_RED); //Rising edge delay 3nS
EPWM_setFallingEdgeDelayCount(EPWM1_BASE, Dead_Band_FED); //falling edge delay 3nS
Yes, that is correct. When you use the DB module it handles the complementary pair generation and inserts dead-band. FED mode is shown in figure 18-34 of this document:
www.ti.com/.../sprui33c.pdf
In the PWM module, you're either generating both A & B patterns by edge placement with the AQ sub-module, or generating one and configuring the DB module to produce the other.
Why do you need dead-band? In the phase shifted pattern you described, none of the edges would be coincident unless the duty cycle reached 50%.
Regards,
Richard
I need it to avoid the short circuit between A and B when they both reach 50% of duty cycle, and also because I have two pwm 3B and 4B inverted to the other 1A and 1B, for the two 3B and 4B I already have a dead band, only missing on ePWM1A and 1B.
Regards
YT
Hi,
can you help about this:
I have a problem with Dead Band on ePWM1B (yellow), if I get Dead Band for Rissing edge on ePWM1B I don't get 180 phase shift between ePWM1A (green) and 1B, so I only have Falling edge on ePWM1B, but I don't get desired Dead Band between 1B and 3A/3B (blue and purple). can you help me about this!
Best Regards
YT
// Dead Band for ePWM1
EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(EPWM1_BASE, EPWM_DB_INPUT_EPWMB); //Configure dead zone input mode
EPWM_setDeadBandDelayPolarity(EPWM1_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_HIGH); // configuration polarity
EPWM_setDeadBandDelayMode(EPWM1_BASE,EPWM_DB_RED,true);
EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED, true); //Configure output mode
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE,EPWM_DB_OUTPUT_A,false);
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE, EPWM_DB_OUTPUT_B, false); //Output is not exchanged
EPWM_setRisingEdgeDelayCount(EPWM1_BASE, Dead_Band_RED); //Rising edge delay 3nS
EPWM_setFallingEdgeDelayCount(EPWM1_BASE, Dead_Band_FED); //falling edge delay 3nS
//Dead Band for ePWM3
EPWM_setRisingEdgeDeadBandDelayInput(EPWM3_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(EPWM3_BASE, EPWM_DB_INPUT_EPWMA); //Configure dead zone input mode
EPWM_setDeadBandDelayPolarity(EPWM3_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(EPWM3_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); // configuration polarity
EPWM_setDeadBandDelayMode(EPWM3_BASE,EPWM_DB_RED,true);
EPWM_setDeadBandDelayMode(EPWM3_BASE, EPWM_DB_FED, true); //Configure output mode
EPWM_setDeadBandOutputSwapMode(EPWM3_BASE,EPWM_DB_OUTPUT_A,false);
EPWM_setDeadBandOutputSwapMode(EPWM3_BASE, EPWM_DB_OUTPUT_B, false); //Output is not exchanged
EPWM_setRisingEdgeDelayCount(EPWM3_BASE, Dead_Band_RED); //Rising edge delay 3nS
EPWM_setFallingEdgeDelayCount(EPWM3_BASE, Dead_Band_FED); //falling edge delay 3ns
We've spent some time going over this and it doesn't appear possible with just one PWM module. Thee DB unit is intended to generate PWM pairs, so you would lose the independence in your A & B channels if you enable it. Basically you can't create the phase shift and have the DB module active.
What I think you're concerned about is reaching 50% duty, in which case edges become aligned and you need dead-band to avoid a shoot-through condition. With the single PWM approach your only solution is to limit the CMPx register loads in software to produce slightly less than 50% duty on each channel, effectively limiting the modulation.
There is a potential solution if you were prepared to use two separate PWM modules to generate A and B. You would configure the time-bases identically and run in zero degree phase relationship, using one to generate the A pulse and the other to generate the B pulse. Each module would use its own DB sub-module configured in active-high complementary mode to generate the deadband. On this device you can link the CMP register writes together to make this simpler, but you are still using separate PWM modules.
I don't see another solution.
Regards,
Richard
what I'm trying to do is just avoid shorting between (ePWM3B: purple) and (ePWM1B: yellow).
I created other pulses with DB (ePWM2A/B) and worked correctly with the signal (green).
Regards
YT
What is the difference between 1B and 3A? Wouldn't 1B with dead-band be the same as 3A?
Regards,
Richard
YT,
I'm wondering - can you just use 3A instead of 1B, since they're the same. What am I missing?
Regards,
Richard
yes they must be equal, but I need the two, and I can't control the two Mosfets with just one pulse, because the two Mosfets have separate potential.there's a way to solve this!Regards
YT
As of today, the only solution I see is to allocate a separate PWM module to generate the A & B pulses, as I described earlier. This is the only short-term solution.
There is one other approach which I think will work. The draw-backs are that it won't be available for another 5-6 weeks, and that the detailed development will be down to you. It is this: the device you are using is equipped with a CLB module which allows users to create their own custom logic. Custom modification of the basic PWM switching patterns is one example of its' intended use. The issue is the tools to allow you to develop with it aren't due for release until the end of 3Q:
https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/816837
That's one only solution I see to stay with A & B generation in the same module and apply dead-band.
Regards,
Richard
i'm now trying to create the separate modules of pwm and because i want to generate a total of 12 pulses for two separate dcdc converters, i need a shift of 90 degrees for each module between A and B. is it possible to move 90 degrees between A and B?
Regards
YT
Hi,
I think with the given configuration of prd =2000 and duty of 20%, it is not possible to get 90 degree phase shift between A & B. You can use different PWM instances to get 90 degree phase shifted PWMs.
Thanks
Vasudha
Hi,
Thanks i got it, now i have a question, it's about the initialization of PWM. how can I set that at 0 Volt all PWM must be equal to zero
Ud1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6); // Messung der ADC
dutyCyclePeriod =(Ud1*EPWM_TIMER_TBPRD/4095); // Formel zur Berechnung von Duty_Cycle
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, dutyCyclePeriod); //DutyCycle für ePWM1A
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-dutyCyclePeriod)); //DutyCycle für ePWM1B
EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A, dutyCyclePeriod); //DutyCycle für ePWM2A
EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_B, dutyCyclePeriod); //DutyCycle für ePWM2B
Regards
YT
Hi,
Youssef Toubla said:how can I set that at 0 Volt all PWM must be equal to zero
What do you mean by "at 0 Volt" ? Usually TBCLKSYNC bit in peripheral clock enable registers allows all users to globally synchronize all enabled ePWM modules to the time-base clock (TBCLK). When set, all enabled ePWM module clocks are started with the first rising edge of TBCLK aligned. For perfectly synchronized TBCLKs, the prescalers for each ePWM module must be set identically.
The proper procedure for enabling ePWM clocks is as follows:
1. Enable ePWM module clocks in the PCLKCRx register
2. Set TBCLKSYNC= 0
3. Configure ePWM modules
4. Set TBCLKSYNC= 1
Thanks
Vasudha
Hi,
sorry my question was not clear, my PWMs are dependent on the AdcResult, when Ud1=0Volt muss all ePWMs equal to zero, that what i mean with 0Volt. how can i configure this in my code ?
Regards
YT
Hi,
You can trip EPWM signals based on an external trip input. Refer to EPWM Trip Zone submodule and CMPSS module for more details.
Thanks
Vasudha