Setting timer3 in CTC mode - conflict with servo library I would like to set up a timer in order to call a function 800 times per second. I'm using the Arduino Mega and Timer3 with a prescaler of 1024. To choose the prescaler factor I've considered the following steps:


CPU freq: 16MHz
Timer resolution: 65536 (16 bits)
Divide CPU freq by the chosen prescaler:
16x10^6/1024=15625
Divide the rest through the desired freq
62500/800=19. 
Put the result + 1 in OCR3 register.


I've used the following table to set registers of TCCR3B:



The error

It is impossible to compile the code. This is the error returned by the compiler:


  Servo\Servo.cpp.o: In function '__vector_32': C:\Program Files
  (x86)\Arduino\libraries\Servo/Servo.cpp:110: multiple definition of
  '__vector_32' AccelPart1_35.cpp.o:C:\Program Files
  (x86)\Arduino/AccelPart1_35.ino:457: first defined here c:/program
  files
  (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe:
  Disabling relaxation: it will not work with multiple definitions


The code

volatile int cont = 0;
unsigned long aCont = 0;
void setup()
{
 [...]
  // initialize Timer3
  cli();          // disable global interrupts
  TCCR3A = 0;     // set entire TCCR3A register to 0
  TCCR3B = 0;     // same for TCCR3B

  // set compare match register to desired timer count: 800 Hz
  OCR3A = 20;
  // turn on CTC mode:
  TCCR3B |= (1 &lt;&lt; WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR3B |= (1 &lt;&lt; CS30) | (1 &lt;&lt; CS32);
  // enable timer compare interrupt:
  TIMSK3 |= (1 &lt;&lt; OCIE3A);
  // enable global interrupts:
  sei();
}

void loop()
{
 // Print every second the number of ISR invoked -&gt; should be 100
 if ( millis() % 1000 == 0)
 {
   Serial.println();
   Serial.print(" tick: ");
   Serial.println(contatore);
   contatore = 0;
 }
}

[...]

// This is the 457-th line
ISR(TIMER3_COMPA_vect)
{
    accRoutine();
    contatore++;
}

void accRoutine()
{
  // reads analog values
}


How to solve the conflict with the servo library?

SOLUTION

Conflict solved using the following code. It compiles but the counter associated with the 800Hz timer doesn't increment its value.

volatile int cont = 0;

void setup()
{
  Serial.begin(9600);
  // Initialize Timer
  cli();          // disable global interrupts
  TCCR3A = 0;     // set entire TCCR3A register to 0
  TCCR3B = 0;     // same for TCCR3B

  // set compare match register to desired timer count: 800 Hz
  OCR3B = 20;
  // turn on CTC mode:
  TCCR3B |= (1 &lt;&lt; WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR3B |= (1 &lt;&lt; CS30) | (1 &lt;&lt; CS32);
  // enable timer compare interrupt:
  TIMSK3 |= (1 &lt;&lt; OCIE3B);
  // enable global interrupts:
  sei();

  Serial.println("Setup completed");
}

void loop()
{
  if (millis() % 1000 == 0)
  {
    Serial.print(" tick: ");
    Serial.println(cont);
    cont = 0;
  }
}

ISR(TIMER3_COMPB_vect)
{
  cont++;
}


Since the main problem has been solved, I've created another question here related to the problem of the counter incrementation.
Unfortunately, The Servo library reserves output compare A (OCR*A) on timers 1,3,4, and 5 when loaded on an arduino mega. Each can only have one ISR, so you will not be able to define your own TIMER*_COMPA_vect while you use Servo without modifying the library. 

However, each hardware timer is equipped with 2 output compare registers. Servo does not claim any TIMER*_COMPB_vect interrupts, so those are free to use, and work exactly the same.

You should watch out for the Servo libraries activities, it could change the configuration of your timer. The default order is on megas is 5,1,3,4 and to give each 12 servos. It only configures the timer once it needs it, so you should be fine using timer 3 until you add that 25th servo.

To change your code, use OCR3B instead of OCR3A (the Output Compare Registers) and set bit OCIE3B instead of OCIE3A in TIMSK3 (the Output Compare Interrupt Enable bits). Then you to change your ISR function to  ISR(TIMER3_COMPB_vect){}

CTC mode only works with OCR3A, but if you set TCNT3 to 0 in your interrupt function you can get similar behavior. Remember to remove the line that turns CTC mode on using WGM12.