Skip to main content
Clarified why count to 7 and 15.
Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126

OK, make themOCR1A and OCR1B both 7:

Why 7? And why 15?

The counts are zero-relative. So by counting to 15 on a 16 MHz processor we are actually getting 1/16th of the clock, namely 1 MHz. And half of that is 8 (which, zero-relative, is 7). So we are really doing:

  • Period: 16 ticks of the 16 MHz clock
  • Duty cycle: 8 ticks of the 16 MHz clock

OK, make them both 7:

OK, make OCR1A and OCR1B both 7:

Why 7? And why 15?

The counts are zero-relative. So by counting to 15 on a 16 MHz processor we are actually getting 1/16th of the clock, namely 1 MHz. And half of that is 8 (which, zero-relative, is 7). So we are really doing:

  • Period: 16 ticks of the 16 MHz clock
  • Duty cycle: 8 ticks of the 16 MHz clock

Added scope shots, extra text.
Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.


The screenshot doesn't show one signal exactly the inverse of the other. The pattern is inverted. If you had a 50% duty cycle, it would be an exact inverse.


It looks good except they overlap (slightly) by 50ns. If I set them to 16 and 8, respectively, they don't overlap but they are slightly asymmetrical

OK, make them both 7:

  ICR1 = 15;
  OCR1B = 7;
  OCR1A = 7;

Now, one cycle:

Scope shot 1

They change over at the same instant - pulse width exactly 500 ns.

Scope shot 2

And they change back at the same moment - pulse width also 500 ns.

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.


The screenshot doesn't show one signal exactly the inverse of the other. The pattern is inverted. If you had a 50% duty cycle, it would be an exact inverse.

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.


The screenshot doesn't show one signal exactly the inverse of the other. The pattern is inverted. If you had a 50% duty cycle, it would be an exact inverse.


It looks good except they overlap (slightly) by 50ns. If I set them to 16 and 8, respectively, they don't overlap but they are slightly asymmetrical

OK, make them both 7:

  ICR1 = 15;
  OCR1B = 7;
  OCR1A = 7;

Now, one cycle:

Scope shot 1

They change over at the same instant - pulse width exactly 500 ns.

Scope shot 2

And they change back at the same moment - pulse width also 500 ns.

Explained about the duty cycle.
Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.


The screenshot doesn't show one signal exactly the inverse of the other. The pattern is inverted. If you had a 50% duty cycle, it would be an exact inverse.

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.

How about this?

void setup()
  {
  // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2
  // Setting DDB1 and DDB2
  DDRB |= bit (DDB1) | bit (DDB2);
 
  // stop timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A = bit (COM1B0) | bit (COM1B1)  // Set OC1B on Compare Match, clear
                                        // OC1B at BOTTOM (inverting mode)
         | bit (COM1A1)                 // Clear OC1A on Compare Match, set
                                        // OC1A at BOTTOM (non-inverting mode)
         | bit (WGM11);                 // Fast PWM, top at ICR1
  TCCR1B = bit (WGM12)  | bit (WGM13)   //       ditto
         | bit (CS11);                  // Start timer, prescaler of 8

  // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1
  ICR1 = 0xFFFF;
  OCR1B = 299;
  OCR1A = ICR1 - OCR1B;

  }  // end of setup

void loop()
  {
  }

Results on a Uno:

Normal and inverted timer output

Output on Uno pins 9 and 10.

Change the prescalers and counters to your desired frequency.


The screenshot doesn't show one signal exactly the inverse of the other. The pattern is inverted. If you had a 50% duty cycle, it would be an exact inverse.

Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126
Loading