Tool/software:








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:








Hi,
I didn't quite understand the issue here.
To try to counter that, I set up a variable to "miss" the first half cycle of the carrier (a simple if condition to by pass the code in the very first ISR trigger), this way "shifting" the code 180 degrees.. to no avail as it can be seen in the next figure:
How are you shifting 180 deg by missing first half cycle ?
I also tried setting TBCTR to start at the same value as TBPRD to force the carrier to start from the top as shown in PLECS, but it also does not work.
Can you explain with simple diagram what you are trying to achieve and what you are getting in same waveform ? When you say it doesn't work, I cant understand what the issue is here. All I see is complimentary pwm signals
Thanks
Hi Prarthan,
Sure, let me explain in simpler terms what my problem is.
The following figure shows two different scope captures inside PLECS.

In Green: The PWM output.
In Red: The Modulating signal, which is the same in both captures.
In Blue: The Triangular carrier, which in the capture at the top starts at 1, whereas in the capture at the bottom starts at 0. That means the top and bottom carriers are shifted 180 degrees apart.
I want to achieve the PWM Output waveform (green) shown at the top capture, but after trying many different things, all I see in the scope is the PWM output shown at the bottom capture (as depicted in dark pink on the real oscilloscope in the original post).
How are you shifting 180 deg by missing first half cycle ?
When I realized the PWM output was not the waveform I wanted to achieve, I tried "missing" the first interrupt routine using the variable "toggle" in an attempt to have the code actually start at the next interrupt cycle. The carrier is a triangular waveform triggering the ADC interrupt at both top and bottom.
This variable is initialized as 0. In the very first interrupt, it bypasses the desired code. The picture below is clear and explains what I mean.

Please let me know if there's any more info I can provide.
Thanks again !
Hi,
In Green: The PWM output.
In Red: The Modulating signal, which is the same in both captures.
In Blue: The Triangular carrier, which in the capture at the top starts at 1, whereas in the capture at the bottom starts at 0. That means the top and bottom carriers are shifted 180 degrees apart.
Yes the above should be possible with starting the counter of the second pwm from TBPRD. TBCTR initial value can be set to TBPRD for this.
Make sure to disable TBCLKSYNC and GTBCLKSYNC then do pwm initialization and then enable TBCLKSYNC after epwm init is done.
Also make sure the shadow loading of the compare value occurs at the desired time bas event. From the above signals looks like the top pwm waveform, compare value changes at counter = TBPRD whereas bottom pwm waveform the compare value changes at Counter=zero. The counter value should also be updated to shadow register before the event occurs.
Thanks
Hi Prarthan,
The CMPA updates are taking place every top and bottom of the carrier. Although it doesn't seem like it from the pictures, it's actually doing that by keeping the same value for two consecutive interrupts, which explains why only at either top or bottom we see the updates.
I tried disabling TBCLKSYNC and GTBCLKSYNC before the pwm initialization and enabling both later, but to no avail.
I also tried setting the counter to start from TBPRD or from 0, but the waveform I wanted to achieve (the one at the top scope capture) still didn't show up.
The shadow registers are set to top and bottom (CMPCTL.bit.LOADMODE = CC_CTR_ZERO_PRD). I even tried changing these values to update at the top only and later at the bottom only, also to no avail.
I am really confused, because I can't seem to make that first waveform show up, although it is a very simple modulation.
The counter value should also be updated to shadow register before the event occurs.
What exactly would this counter be in this situation? The CMPA register is already being updated at ZERO and TBPRD as shown previously. But I'm not sure what that would be now.
Thanks for your support !
Hi,
Can you show in oscilloscope waveform what is missing ? I cant correlate the oscilloscope shot to PLECS scope output.
Also the scope shot that you are showing, what are the top and bottom pwm waveforms ? Are they output of same epwm meaning epwma and epwmb ? or they are different pwm instance outputs ?
If you are expecting same channel pwm output, pwma and pwmb to overlap in time then why do you have the epwm in complementary mode ?
The CMPA updates are taking place every top and bottom of the carrier.
I don't understand why you would update compare values at PRD (top) and Zero(bottom) when your compare values are supposed to shadow load to active only on either of these two events for the respective pwm as I mentioned earlier.
What exactly would this counter be in this situation? The CMPA register is already being updated at ZERO and TBPRD as shown previously. But I'm not sure what that would be now.
Shadow to active load event decides when the value in shadow register is loaded to active register (the value that is in effect). If its not updated it will shadow load previous or existing value in shadow register.
Thanks
Hi Prarthan,
Can you show in oscilloscope waveform what is missing ? I cant correlate the oscilloscope shot to PLECS scope output.
Also the scope shot that you are showing, what are the top and bottom pwm waveforms ? Are they output of same epwm meaning epwma and epwmb ? or they are different pwm instance outputs ?
If you are expecting same channel pwm output, pwma and pwmb to overlap in time then why do you have the epwm in complementary mode ?
I'll explain in a different way. Let me show what I mean.
Left picture : the one I want, as in PLECS.
Right picture: the one obtained from the real oscilloscope.


The code used to generate them are exactly the same. Updating at the top and bottom of the carrier waveform.
I don't understand why you would update compare values at PRD (top) and Zero(bottom) when your compare values are supposed to shadow load to active only on either of these two events for the respective pwm as I mentioned earlier.
Yes, in this case you are right and it could be updated only at the top or only at the bottom, but that should not be the problem since CMPA values are programmed to be the same for two interrupt cycles. As it can be seen in PLECS, the C-script I used is exactly the same used in the ADC_ISR in Code Composer Studio, both triggering at either top or bottom. I can share the full PLECS file too if needed.
Shadow to active load event decides when the value in shadow register is loaded to active register (the value that is in effect). If its not updated it will shadow load previous or existing value in shadow register.
I see, but isn't that already what's been programmed through the pwm init as shown below?
Then, I tried changing the start of the counter at the TBCTR register, starting at 0 or at TBPRD, to no avail. The waveforms don't look like what I expected them to be. Then I changed SOCASEL to update only at the bottom, then later only at the top, yet none would give me the desired waveform shown in PLECS.
If there's anything more I can share please let me know.
Thanks for your help!
Hi,
Left picture : the one I want, as in PLECS.
Right picture: the one obtained from the real oscilloscope.
For the above desired and obtained wave. What is not matching ?
The gap after the second pulse in desired wave is missing ? Other pulses/waveform is matching ?
Which means the in the top pwm the falling events (CMPA up count event) are missing ?

Thanks
For the above desired and obtained wave. What is not matching ?
The gap after the second pulse in desired wave is missing ? Other pulses/waveform is matching ?
Which means the in the top pwm the falling events (CMPA up count event) are missing ?
Hi Prarthan,
Actually, the other pulses are not matching either. The first pulse in the desired wave is shorter than the first pulse in the obtained wave.
The gap after the second pulse is indeed missing, which is also part of the problem I'm having hard a time to understand why, but even if that was fixed, the pulse length would still not be matched.
In summary, the desired waveform is not showing up. I tried changing the carrier phase-shift by 180 degrees but it also didn't work.
Thank you for your help!
Looks like the CMPA value can be greater than period with duty being set to 1.1 when count > 3. I think the compare events does not happen, which may explain the missing pulses. CMPA should be set < PRD for the pin action on compare event.
Calculate the desired pulse width of your desired waveform in terms of the TBCLK and adjust the CMPA values (or duty) to adjust the pulse width.
Hi Joe,
That's it.
I reduced duty to 0.9999, and now I've got the desired waveform as it's supposed to be, perfectly.
HOWEVER that created another problem in the other waveform, the one which uses the carrier phase-shifted 180 degrees: Since CMPA needs to be < PRD, what's the appropriate way to replicate a duty >= 1, which means a fully on/high PWM signal?
The 180-degree shifted waveform now faces a very small spike, which matches the exact moment the wave crosses the top of the carrier in PLECS.
Before:

After:
Hi Henrique,
This pwm module is very flexible and can be configured many ways to fit your needs -
I think the glitch can be removed by allowing duty to be 100%, provided that the period event configured to bring the pin low also - make sure that CMPA is clipped to PRD.
AND, pulses are supposed to be centered around ZERO in your current design, loading CMP from shadow on CTR eq ZERO event will create uneven/undesirable pulse width. Change the CMP shadow load event as CTR eq PRD to generate clean pulses.
Hi Joe,
AND, pulses are supposed to be centered around ZERO in your current design, loading CMP from shadow on CTR eq ZERO event will create uneven/undesirable pulse width. Change the CMP shadow load event as CTR eq PRD to generate clean pulses.
I tried setting CMP shadow load to be equal to PRD but it did not work as intended. Also I checked on the datasheet and it seems like it's actually possible to have values greater than TBPRD, but it seems like when implementing that, the uC won't generate the appropriate response.
In the datasheet it even says "If CMPA/CMPB is ≥ TBPRD, the event occurs on a
period match (TBCTR = TBPRD)." So in my previous case, setting the duty cycle to 1.1 to force a high should work according to the datasheet, shouldn't it?
I tried setting CMP shadow load to be equal to PRD but it did not work as intended. Also I checked on the datasheet and it seems like it's actually possible to have values greater than TBPRD, but it seems like when implementing that, the uC won't generate the appropriate response.
TRM is a good reference - try all steps below together:
1. Limit CMPx to PRD
2. Set PRD event to set the pin low in addition to CMP dn/up events setting the pin high/low
3. Select CMP load from shadow on PRD event only