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.

PWM Instability When Varying Duty Cycles

Other Parts Discussed in Thread: EK-TM4C123GXL

Looking for help. I'm working toward building a DC/AC inverter, using the EK-TM4C123GXL to control 4 gate signals being sent to FET's in an H-bridge, also using Code Composer Studio v6.

Right now I am just trying to get one gate signal to switch between two duty cycles, which are defined in an array. 

The variations in PWM outputs are inconsistent. Duty cycles are set to HIGH (~90%) and LOW (~10%), count-down timer and should alternate one at a time, but sometimes each will occur twice in a row. See the oscilloscope screencap below.

Looking further at the PWM outputs, it appears as though there is a pattern to when the HIGH and LOW duty cycles double up (HHL  HHLL  HLL and so on, where H=HIGH and L=LOW), so the issue might be some sort of timing error involving the interrupts. Interrupts are set to trigger at the end of each PWM period, at which the duty cycle is changed to the next value in an array.

The microprocessor is set to the default CPU speed of 8 MHz, PWM signals are set to run at 2.16 kHz.

Does anyone know what might be causing this and how to fix it? Let me know if you need more info.

Thanks!

  • Hello Timothy,

    What is the method being used for loading the value. Is it set to Immediate or Load on timeout. There is no code nor any register dump that be used to see the configuration of the PWM.

    Regards
    Amit
  • Are you using the synchronous load features of the PWM block? You can get some interesting failures if you update PWM registers on the fly in a way that confuses the block. You should include your handler code. You'll also want to provide more information about the interrupts in your environment. Is the PWM handler the highest priority hander?
  • Hello Robert,

    I am thinking on the same lines as you have written in your last post.

    PWMGenConfigure needs to have the parameter PWM_GEN_MODE_GEN_SYNC_LOCAL

    Regards
    Amit
  • Hi Amit,

    We noted poster's mention of "four" gate control signals.

    Might this be an opportune time for you to describe the "operational" differences (and advantages) between, "GEN_SYNC_LOCAL & GEN_SYNC_GLOBAL?"

    I agree w/you & other poster that "SYNC" proves useful - yet the differences between "LOCAL & GLOBAL" should prove of value to many. (especially moi) Merci.

  • Below is the link to my code files. I also am assigning and updating registers manually, not using the typical TI code that seems to be what most people online use.

    drive.google.com/.../view

    Amit, PWM duty cycles are being updating using the LOAD command.

    R Sexton, PWM interrupts are the highest priority, they're the only ones set. I'm unsure if I am using synchronous load features or not (whichever the default is).

    Thanks for your help guys!
  • Hello Timothy

    Unfortunately TI network blocks out Google Drive. I cannot access the link. Can you please attach the files to the form post using "Use rich formatting" link on the bottom right of the reply panel.

    Regards
    Amit
  • You need to spend some time with the data sheet.   The PWM block is too complex to understand from the API alone.   Per the data sheet, the synchronous update features are off by default.     Synchronous update is the mode thats designed for your application.

  • Hello cb1

    The two work almost the same except in the GLOBAL option there is a qualifier which is under CPU control

    GEN_SYNC_LOCAL is applied only to the generator when it decrements to 0
    GEN_SYNC_GLOBAL is applied to the generator when it decrements to 0 AND the corresponding Generator bit in PWMCTL is set to 1.

    The GLOBAL options allows the user to load the value but the counter will not use the value unless there is a qualifier. This way the CPU can pre-compute the value and only perform the update when a specific soft condition occurs.

    Regards
    Amit
  • Hi Amit,

    Thank you - much appreciated - the use of the word, "Global" does not (really/conclusively) suggest ANY (necessary) "qualifier" - don't you agree?  (Global typically suggests "universal (at best) and multiple (more often) - neither the (apparent) case here.)  

    I'd propose "GEN_SYNC_CNT_0_QUAL" which I believe (far) better describes the operation & avoids the unfortunate (mis)use of "Global."   (investors have long taught, "Never criticize w/out providing a (superior) alternative" - this writing represents my attempt in that direction)

    And - maybe I'm (especially) thick - but are you saying that the corresponding bit w/in, "PWMCTL" - when NOT "set to 1" - enables "GEN_SYNC_LOCAL"  to function normally - but prevents "“GEN_SYNC_GLOBAL" from performing the desired, PWM Update?   (perhaps read this twice - I've tried my best to be precise in this tech wording...)
     
    MCU manual makes slight - yet we believe ineffectual - effort to explain (Global vs. Local).   Comprehension was traded (I believe) @ the altar of brevity - (always "love" that.)  [5 added, tech-writer minutes - traded for 5+ hours (or more) "head-scratching" by (multiple) hapless users...]

  • Hello cb1,

    At the face value, no, it does not.

    Regards
    Amit
  • Amit Ashara said:
    At the face value, no, it does not.

    Sorry - brevity over-challenges - I (and I suspect others) cannot comprehend:

    • Does the corresponding bit w/in, "PWMCTL" - when NOT "set to 1" - enable "GEN_SYNC_LOCAL"  to function normally?
    • Does that same bit - (unset = 0) prevent "“GEN_SYNC_GLOBAL" from performing the desired, PWM Update?   How is this noted (are faults generated?
  • Hello cb1,

    Yes, cb1 that is correct.

    Regards
    Amit
  • I'll go quietly... Thank you.   (2 questions yield 1 response...)

  • Its in the data sheet.

    The bits that control this behavior are in PWMENUPD.

    PMCTL is also described. Its not a configuration register - its for triggering updates.
  • I remain in full challenge w/the correctness of "Global" - also appearing w/in the data sheet.
  • Hello Robert

    I hope we are all speaking in context of the PWMxCTL register where the Global Sync is being defined: "Updates to the register are delayed until the next time the counter is 0 after a synchronous update has been requested through the PWMCTL register."

    Regards
    Amit
  • I'll try again - my objection is with the use of the word, "Global." I've earlier detailed what the "standard" definitions of "global" suggest. I've also proposed a label superior to "Global." (my belief)

    I recall our firm's experimenting w/"Local vs. Global." Our results do not agree w/what's been stated here. (note that ours were achieved via LM3S & LX4F)   Our use case employed the MCU as the controller for 3 phase, BLDC motors.   Our PWM switching effects/impacts - (via the API) between "Sync_Local" and "Sync_Global" - were barely noted!    (perhaps UN-noted!)  
     
    As I often write (& nego) tech contracts - my interest in "precision wording" may exceed the "norm" here...   Global is a (very) poor word choice as used herein...

  • Hi Timothy,

    Depending on where the duty cycle is being updated, perhaps in the interrupt handler? It has been an issue PWM interrupts should be cleared twice on entrance into the handler to insure immediate re-entrance is avoided. That PWM interrupt clearing errata is well known, seems to be difficult to fix at the silicon level since it spans across series of MCU.  Rest assured double clearing PWM interrupt seems to always catch the second one if it missed on the first.

    My question to Amit would be - does this same PWM interrupt errata occur at the timer level with PWM configured for CCP interrupt events?  

  • Hello Tim

    Your configuration looks fine and all the settings required for the Comparators are fine.

    The issue it seems is because of interrupt handler.

    (*_PWMISC)=(0<<0);
    (*_PWMISC)=(0<<1);

    The bits are Write 1 to clear and write 0 to clear.

    Regards
    Amit
  • Hi CB1,

    Seem to think Global updates all the selected gen timers sync bits simultaneously and local updates only the (single) generator timer due the PWMCTRL bit Amit mentions.

    Recently pondered sensing Global update events via GPIO ports/triggered updates to all PWM controllers in a cluster group. Perhaps Global synchronous update might remove the hazards seemingly present in PWM clock phase difference among peer members in said groups, remains questionable.

    The need for parallel processors in DC to AC inverter technology has yet to emerge in any useable topology, motor ware included.
  • To clarify - (single) inferring a local timers zero timeout event has occurred as if (PWM_GEN_MODE_NO_SYNC) is configured. Seems motor ware typically uses Local Sync Update mode; Updates to all generators occur on zero count but the new count value is write deferred until the end of the current PWM cycle.

    The main difference seems to be the Global control bit when set allows writing different and or individual count values for each generator yet also write deferred until the end of each PWM cycle. Sync update global might work well for PWM clusters accounting for propagation delay of remote peer triggers indicating a sync update cycle has occurred.
  • Amit,

    I'm not quite sure what you mean. I'm using (*_PWMISC)=(0<<0) to clear the interrupt from PWM Module 0 once it triggers the function changeDC0A. Is this not being used correctly?

    -Tim

  • Hello Tim,

    As per the definition of PWMISC register, the interrupt condition is cleared by writing 1 to the corresponding bit location and not 0.

    Regards
    Amit
  • Amit,

    Thanks. Unfortunately that didn't solve the problem. My PWM is now stable, but not varying. It's set to the first value in the array of compare register values. I set up global synchronizing (PWMISC) and enabled the PWM updates (PWMENUPD) based on what some of the other mentioned as well. It seems as though the interrupt is either not triggering or something is not set up properly to change the PWM duty cycle when the interrupt occurs.

    Still digging through the datasheet, do you have any other suggestions?

    Thanks,
    -Tim
  • Try adding a counter to your ISR to verify whether or not it's firing.
  • Hello Tim,

    Can you toggle a GPIO H->L->H in ISR to see if it is getting invoked properly?

    Regards
    Amit
  • Believe that a "hybrid" of the 2 ISR "monitors" may achieve best results.

    Counter may update too fast to be clearly visible.  (while running real time)
    and
    Toggle of GPIO will require a scope.   (while running real time)

    By toggling that GPIO (driving an Led) every "n" ISR counts - the essence of each idea remains - yet the (very real) benefits of real time operation monitoring are enabled.