1

Is it possible to simultaneously output a clock signal and it's inverse using the timer register(s)?

I'm using the following code in arduino to output a 1MHz signal on OC1A:

//Use Timer/Counter1 to generate a 1MHz square wave on Arduino pin 9.
//J.Christensen 27Apr2012

void setup(void)
{
    DDRB = _BV(DDB1);                  //set OC1A/PB1 as output (Arduino pin D9, DIP pin 15)
    TCCR1A = _BV(COM1A0);              //toggle OC1A on compare match
    OCR1A = 7;                         //top value for counter
    TCCR1B = _BV(WGM12) | _BV(CS10);   //CTC mode, prescaler clock/1
}

void loop(void)
{
}
4

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 OCR1A and OCR1B both 7:

  ICR1 = 15;
  OCR1B = 7;
  OCR1A = 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

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.

|improve this answer|||||
  • 1
    Thanks! I was able to get a 1Mhz square wave by eliminating the prescaler and setting ICR1 = 15 and OCR1B = 7. 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. – rob Sep 1 '15 at 2:12
  • 1
    See amended reply for how to fix this. – Nick Gammon Sep 1 '15 at 2:56
1

Various AVRs have the capability to output both the normal and inverted timer waveform from a single output compare register simultaneously on two pins. These devices include, but are not limited to, ATtinyX5/V, ATtiny26/L, ATtinyX61A, and ATmegaXXU4.

The ATmega328P does not have this capability, therefore the smallest primary source Arduino that does is the Leonardo (ATmega32U4) and comparable devices. The Adafruit Trinket and the Digispark (both ATtiny85-based) also offer this.

|improve this answer|||||
0

What about also setting COM1B0 and then setting the initial values of OC1A and OC1B to opposites by writing to PORTB?

Also, I presume you mean 1 MHz and not 1 mHz?

|improve this answer|||||
0

Another option is to do this in hardware - it's trivial to invert a signal.

For example, see the selected answer for https://electronics.stackexchange.com/questions/30238/how-to-invert-a-digital-signal - the second diagram - connect Vs to your clock, and Vo will be your inverted clock. For the two resistors, anything over 1k should be fine. Or use an inverter (which is the same thing, in one component, but is much less likely to be in your random-part box).

Note: There will be a very short delay going through this circuit - one place I saw suggested 1.5ns, but see the spec sheet of your transistor. A 1mhz clock "ticks" at 1,000ns (I guess, 500ns on, 500ns off), so this delay shouldn't be significant.

|improve this answer|||||
  • Thanks, I originally tried to use an op amp to invert the signal and was surprised by how slow it was – it took about 10µs to switch. This probably would have been a faster, better approach, but if I can do everything in software that would be ideal. – rob Aug 31 '15 at 16:55
  • This is out of my field of expertise a bit, but op-amps have a slew rate, which I believe means the time to change states. For example the LM158 is quoted as having 0.3 V/µs which means therefore to go from 0 to 5 V would take 5 / 0.3 = 16.66 µs, which is fairly close to your observations. You can get faster op-amps. – Nick Gammon Sep 1 '15 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.