user22928: The concept:
Play a sine wave saved as a character array in PROGMEM through an 8-bit DAC connected to the PORTC pins on the Arduino Mega.
This works:
// File just defines an array and a size

#include "sine440.h"

int i = 0;
void setup() {
  DDRC = B11111111;
}

void loop() {
  PORTC = pgm_read_byte(&sine[i++]);
  if(i >= sine_size){
    i = i - sine_size;
  }

  delayMicroseconds(60);
}

The above code produces a sine wave of about 440 Hz, exactly what I wanted. Now, I'd like to move this into an interrupt routine, as follows:
This doesn't work
#include "sine440.h"

int i = 0;
void setup() {
  DDRC = B11111111;
  TCCR5B = (1 << WGM52) | (1 << CS50 );
  OCR5A =  16000000/16000;
  TIMSK5 = (1 << OCIE5A);
}

ISR(TIMER5_COMPA_vect){
  PORTC = pgm_read_byte(&sine[i++]);
  if(i >= sine_size){
    i = i - sine_size;
  }
}

void loop() {

}

The above code produces a sine wave of 1721 Hz. I know that this means it's iterating through the array too fast, but I don't know how to change it. In order for it to produce 440 Hz, it needs to be preforming 16,000 iterations per second, which is what I believe  OCR5A =  16000000/16000; does. But it doesn't appear that changing the value of OCR5A does anything at all. Giving it the max value of 65,535 still produces a 1721 Hz sine wave...
So what am I doing wrong here? How do I change the speed of this timer interrupt?

user2944: I second BrettAM's comment. The Arduino IDE sets most of all the timers up for PWM, and I had to comment out a section once to use my own ISR with Timer 3 on a 32u4, because no matter where or how I set it, the CTC interrupt never went. The WGM50 and CS51 are set at the start of the Arduino files basically, so that messes with your settings.
You will need go into the Arduino core files. This is $install_path/arduino-1.x.x/hardware/arduino/avr/cores/arduino/, and under that directory you need to find file wiring.c. This file contains all the setup of the timers for PWM and the millis() or micros() functions.
Go to line 342. Located there is this:
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)

  sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
  sbi(TCCR5B, CS50);
  sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

#endif

Here you can place another #if defined() macro around this, resulting in:
#if !defined(doNotSetTimer5)

  #if defined(TCCR5B) && defined(CS51) && defined(WGM50)

    sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
    sbi(TCCR5B, CS50);
    sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

  #endif

#endif

Now when you want to use your custom settings, you will put the following at the top of your .ino file:
#define doNotSetTimer5
#include <wiring.c>

That does not block the Arduino environment from setting up Timer 5 when compiled with other code, but only when you want to use custom settings (changed because of @Gerben's suggestion). When you change these settings you will lose PWM on 3 pins: 44 45 46. But you will be able to make use of setting your own PWM up or a CTC ISR().
This doesn't mess with anything else and is the easiest way to do it.

22928: <p><strong>The concept:</strong></p>
<p>Play a sine wave saved as a character array in PROGMEM through an 8-bit DAC connected to the PORTC pins on the Arduino Mega.</p>
<p><strong>This works:</strong></p>
<pre class="lang-c++ prettyprint-override"><code>// File just defines an array and a size

#include &quot;sine440.h&quot;

int i = 0;
void setup() {
  DDRC = B11111111;
}

void loop() {
  PORTC = pgm_read_byte(&amp;sine[i++]);
  if(i &gt;= sine_size){
    i = i - sine_size;
  }

  delayMicroseconds(60);
}
</code></pre>
<p>The above code produces a sine wave of about 440 Hz, exactly what I wanted. Now, I'd like to move this into an interrupt routine, as follows:</p>
<h3>This doesn't work</h3>
<pre class="lang-c++ prettyprint-override"><code>#include &quot;sine440.h&quot;

int i = 0;
void setup() {
  DDRC = B11111111;
  TCCR5B = (1 &lt;&lt; WGM52) | (1 &lt;&lt; CS50 );
  OCR5A =  16000000/16000;
  TIMSK5 = (1 &lt;&lt; OCIE5A);
}

ISR(TIMER5_COMPA_vect){
  PORTC = pgm_read_byte(&amp;sine[i++]);
  if(i &gt;= sine_size){
    i = i - sine_size;
  }
}

void loop() {

}
</code></pre>
<p>The above code produces a sine wave of 1721 Hz. I know that this means it's iterating through the array too fast, but I don't know how to change it. In order for it to produce 440 Hz, it needs to be preforming 16,000 iterations per second, which is what I believe <code> OCR5A =  16000000/16000;</code> does. <strong>But</strong> it doesn't appear that changing the value of OCR5A does anything at all. Giving it the max value of 65,535 still produces a 1721 Hz sine wave...</p>
<p>So what am I doing wrong here? How do I change the speed of this timer interrupt?</p>
 2944: <p>I second BrettAM's comment. The Arduino IDE sets most of all the timers up for PWM, and I had to comment out a section once to use my own ISR with Timer&nbsp;3 on a 32u4, because no matter where or how I set it, the CTC interrupt never went. The <code>WGM50</code> and <code>CS51</code> are set at the start of the Arduino files basically, so that messes with your settings.</p>

<p>You will need go into the Arduino core files. This is <code>$install_path/arduino-1.x.x/hardware/arduino/avr/cores/arduino/</code>, and under that directory you need to find file <code>wiring.c</code>. This file contains all the setup of the timers for PWM and the <code>millis()</code> or <code>micros()</code> functions.</p>

<p>Go to line 342. Located there is this:</p>



<pre class="lang-cpp prettyprint-override"><code>#if defined(TCCR5B) &amp;&amp; defined(CS51) &amp;&amp; defined(WGM50)

  sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
  sbi(TCCR5B, CS50);
  sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

#endif
</code></pre>

<p>Here you can place another <code>#if defined()</code> macro around this, resulting in:</p>

<pre class="lang-cpp prettyprint-override"><code>#if !defined(doNotSetTimer5)

  #if defined(TCCR5B) &amp;&amp; defined(CS51) &amp;&amp; defined(WGM50)

    sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
    sbi(TCCR5B, CS50);
    sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

  #endif

#endif
</code></pre>

<p>Now when you want to use your custom settings, you will put the following at the top of your .ino file:</p>

<pre class="lang-cpp prettyprint-override"><code>#define doNotSetTimer5
#include &lt;wiring.c&gt;
</code></pre>

<p>That does not block the Arduino environment from setting up Timer&nbsp;5 when compiled with other code, but only when you want to use custom settings (changed because of @Gerben's suggestion). When you change these settings you will lose PWM on 3 pins: <code>44 45 46</code>. But you will be able to make use of setting your own PWM up or a CTC <code>ISR()</code>.</p>

<p>This doesn't mess with anything else and is the easiest way to do it.</p>
