two 200kHz complementary PWM Signals

stuart0 wrote

Thinking a bit more about doing it all internally. You could get complimentary signals, with dead time included, as follows.

  1. Use the timer in dual slope PWM mode, no prescaler.

  2. Set one output compare unit for normal (clear on rising slope) PWM and the other output compare unit for complementary (set on rising slope) pwm.

  3. Set the compare unit for the non-complementary output to be 1 count less than half scale, and the complementary one to be 1 count more than half scale. This gets you two clocks (125ns) of dead time.

The problem of course is that you can't get 200kHz with both compare units in operation like this. You are basically stuck with about 31kHz operation because the of the full count timers and the dual slope operation.

This is a good idea, but you can get 200Hkz by using Timer1 on the uno. Timer1 is a 16 bit timer with input capture, and there is an extra register available to use for TOP and still get hardware output on two pins. You use a PWM mode with a top count of ICR1. But, as stuart0 says, the duty cycle will be 47.5% to get dead spaces of 125 ns between pulses.

Mode 10 is PWM(dual slope) to ICR1 top count. If ICR1 = 80 and no prescaler, than then the period is 5 microseconds for 200KHz.

//Timer1 Mode 10 PWM to ICR1
//Dual pin 200KHz PWM generator
//47.5% duty cycle 125ns dead band between pulses

void setup() {
  pinMode(9, OUTPUT); //output A
  pinMode(10, OUTPUT); //output B

  TCCR1A = 0; //clear timer registers
  TCCR1B = 0;
  TCNT1 = 0;

  //ICR1 and Prescaler sets frequency
  //no prescaler .0625 us per count @ 16Mh
  //80 counts x .0625 = 5 us = 200Khz

  TCCR1B |= _BV(CS10); //no prescaler
  ICR1 = 40;//PWM mode counts up and back down for 80 counts

  OCR1A = 21; //Pin 9 match
  //output A set rising/clear falling
  //Rise at TCNT 21 upslope, High 38 counts, Fall at TCNT 21 downslope
  //47,5% Duty Cycle Pulse centered on TCNT 40. High 38 Low 42
  TCCR1A |= _BV(COM1A1) | _BV(COM1A0); //output A set rising/clear falling

  OCR1B = 19; //Pin 10 match
  //output B clear rising/set falling
  //Fall at TCNT 19 upslope, Low 42, Rise at TCNT 19 downslope
  //47.5% Duty Cycle Pulse centered on TCNT 0. High 38 Low 42
  TCCR1A |= _BV(COM1B1); //output B clear rising/set falling

  TCCR1B |= _BV(WGM13); //PWM mode with ICR1 Mode 10
  TCCR1A |= _BV(WGM11); //WGM13:WGM10 set 1010

}

void loop() {}
1 Like