Generating 2 PWM signals with 1 timer of XMEGA A1U

1 post / 0 new
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0



Is there a way to generate 2 separate PWM signals using compare channels of timer 0/1 of XMEGA A1U, considering that start and stop timings are different. (XMEGA A1U)



PER = 80 us,

Signal 1 is high from 0 to 20 us of a period.

Signal 2 is high from 40 to 70  us of a period.


The signals have to be controlled absolutely precise, jitter free, using the timer's OC units, not inside an interrupt, not to mention polling the timer flags.

I cannot use a second timer (I have no spare timer that can be used for PWM control, I'm using all eight). If I had free timer, I'd run it with an offset and use it to control the second signal.

I prefer not using Event system -> DMA - I know I can solve the problem with that, using 2 timer events to toggle any pin.

Also, this has to be done runtime, without stopping the timer.


I used to do that control with timer 4/5 of XMEGA E5, but timers 4/5 had the possibility to set the polarity of the PWM control, timers 0/1 can't (I can invert the pins themselves, but that doesn't help in my solution).

Thus inside 1 period I used to reconfigure the CCB channel to set up a second event with inverted polarity, so the first compare match with generate the rising front of the signal and the second compare match of the same CC channel - the falling front (or vice versa).

I used 2 entries in interrupt to do that to reconfigure CCB, but it worked.


Here is what I previously did:

#pragma interrupt_handler   TCC4_CCB_interrupt:iv_TCC4_CCB
void TCC4_CCB_interrupt (void)
    unsigned char sreg = CPU_SREG;

    if (TCC4_ctrlState == 0) //first entry
        TCC4_CTRLC &= ~(TC4_LCMPB_bm); //prepare toggling of CCB in second entry
        TCC4_CTRLC |= TC4_HCMPB_bm; //0b00100000

        TCC4_CCB = secondEntryTime;
        TCC4_ctrlState = 1;
        TCC4_CTRLC &= ~(TC4_HCMPB_bm); //prepare toggling of CCB in first entry
        TCC4_CTRLC |= TC4_LCMPB_bm; //0b00000010

        TCC4_CCB = firstEntryTime;
        TCC4_ctrlState = 0;
    TCC4_INTFLAGS = TC4_CCBIF_bm; //clear interrupt flag
    CPU_SREG = sreg;

Any ideas how I can achieve the same effect with XMEGA A1U?


P.S. Another difference I noticed is that turning off a CCExEN for a specific pin runtime behaves differently:

 - timer 0/1 (XMEGA A1U) - TCC0_CTRLB waveform control disable does nothing, until the next timer update event - output state is still controlled by the PWM, even if CCxBV and CCxIF are cleared and CTRLFSET is used for update command - nothing resets that pin

 - timer 4/5 (XMEGA E5) - TCC0_CTRLB waveform control disable immediately returns the standart control of the output - (PORTx_OUT)