Timer in CTC mode to generate 1MHz pulse

Hi folks. I'm using the following code to generate a 1MHz pulse and output it at pin 13. I'm using the Arduino Uno Rev3, with an on-board 16MHz clock. This is my code:

#define myOutputPin 13
int toggle = 0;
void setup()
{
  pinMode(myOutputPin, OUTPUT); 
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 8;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
}

ISR(TIMER1_COMPA_vect)
{
  digitalWrite(myOutputPin, toggle == 0 ? HIGH : LOW);
  toggle = ~toggle;
}

void loop(){}

I measured the frequency of the generated signal using a 50MHz oscilloscope and it's just 51.55kHz - far from the desired value of 1MHz. What is the problem in the code? Is it at all possible to generate a signal of such a frequency? Is there some operation that consumes computational power and renders my frequency estimation too ambitious?

As you can see I'm not using any pre-scaler (TCCR1B |= (1 << CS10);) and I have calculated the compare-match value using the formula CM=f_cpu/prescaler/f_desired/2 where f_cpu=16Mhz, prescaler=1 and f_desired=1MHz, so CM=8, thus I used OCR1A = 8.

And yet another incomprehensible phenomenon: when I switch to pin #9, the frequency I measure becomes 48.08kHz and at pin #10 it is 45.87kHz. Something very strange is going on...

Your problem is that interrupt service routines take a finite time to execute, maybe 2.5 uS in overhead, plus your digitalWrite, etc.

So you can't execute an ISR every 3 or 4 uS and hope to get a 1 uS pulse out of it.

However this sketch (which uses the hardware timer output) reliably outputs 1 MHz on pin 9:

#define myOutputPin 9

void setup ()
{
  pinMode (myOutputPin, OUTPUT); 
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 7;   // toggle after counting to 8
  TCCR1A |= (1 << COM1A0);   // Toggle OC1A on Compare Match.
  TCCR1B |= (1 << WGM12);    // CTC mode
  TCCR1B |= (1 << CS10);     // clock on, no pre-scaler
}
void loop () { }

Note that OCR1A is 7, not 16. For one thing it is zero-relative (so you should have used 15 not 16) and it takes two toggles per cycle, so we really want to toggle every 8 clock cycles of the processor (ie. every 500 nS).

More info:

Thank you very much for the hints and for the code which - by the way - works perfectly fine. I would like us to break it down a bit for me to understand the details. Firstly, I noticed that you have only indicated pin #9 as an output using pinMode (myOutputPin, OUTPUT) but I don't see how you forward the generated signal to this output pin. What if we need to send it to pin #9? (I changed 9 to 10 but it didn't work. Is Timer 1 bound to pin #9?) This is OC1A - isn't it?

Additionally, why it is ok to remove the line TIMSK1 |= (1 << OCIE1A) from my code? I mean, the goal here is to enable the timer/counter interrupt mask register (TIMSK1) so as to enable timer interrupts and this is the point of that line.

As described on the page I linked to, each timer has an A and B side, and those sides can be commanded to toggle/set/clear a fixed pin, as per this table:

Timer 0

input     T0     pin  6  (D4)
output    OC0A   pin 12  (D6)
output    OC0B   pin 11  (D5)

Timer 1

input     T1     pin 11  (D5)
output    OC1A   pin 15  (D9)
output    OC1B   pin 16  (D10)

Timer 2

output    OC2A   pin 17  (D11)
output    OC2B   pin  5  (D3)

So, OC1A can affect Arduino pin 9 (pin 15 on the actual chip).

I mean, the goal here is to enable the timer/counter interrupt mask register (TIMSK1) so as to enable timer interrupts and this is the point of that line.

Yes, but you can't process interrupts that fast, as I said. The hardware however can toggle the pin at any reasonable rate. Instead of using interrupts, let the hardware do it. In any case, interrupts can be out a bit if another interrupt happens to be active at the time (eg. Timer 0).

Hi guys, I'm quite new to Arduino so sorry for maybe stupid question, but I'm wondering why you have to set TCCR1A and TCCR1B registers to 0, aren't they set to 0 by default according to datasheet?

Cheers

Biorez

Better safe than sorry. Some other program may have altered those registers after startup.

Thanks for the simple but didactic code.

And how could I add a second Output Pin with a 90 degree Phase shift,
( and optionally a third Pin with a 180 degree Phase shift synchronized) ?

Thanks
Pat

You failed to mention the processor.

And how could I add a second Output Pin with a 90 degree Phase shift,
( and optionally a third Pin with a 180 degree Phase shift synchronized) ?

Phase-shifting outputs at 1 MHz on
Arduino Nano 3.0 ATMega328 ?

Pathu:
Arduino Nano 3.0 ATMega328 ?

To get the three outputs you want on an AVR processor you will have to use three timers. The m328 processor has three timers. Which means you will have to give up millis / micros; you will not be able to use a timer for anything else.

Is that going to work for your application?

at 1 MHz

With a processor running at 16 MHz that gives you 16 steps.

Is that going to work for your application?

You might also want to look at this material about synchronizing the timers.

2 timers are needed for signal and for 90deg phase shift. The third is luxury, not absolutely needed (180 degree phase shift might be done by logical negation without phase shift?).
Will check the ref,too.

You write "To get the three outputs you want on an AVR processor you will have to use three timers. The m328 processor has three timers. "

Could I also use a single timer, with the A side toggling an output at 7 and the B side toggling another output at 3, to get two outputs with 1 MHz but with phase shift?

That may work. I have not used inverted output.

Could I also use a single timer, with the A side toggling an output at 7 and the B side toggling another output at 3, to get two outputs with 1 MHz but with phase shift?

Yes.