Me gustaría configurar un temporizador para llamar a una función 800 veces por segundo. Estoy usando Arduino Mega y Timer3 con un preescalador de 1024. Para elegir el factor de preescalador, he considerado los siguientes pasos:
- Frecuencia de CPU: 16MHz
- Resolución del temporizador: 65536 (16 bits)
- Divide CPU frec por el prescaler elegido: 16x10 ^ 6 / 1,024 mil = 15,625
- Divida el resto entre la frecuencia deseada 62500/800 = 19 .
- Ponga el resultado + 1 en el registro OCR3.
He usado la siguiente tabla para establecer registros de TCCR3B:
El error
Es imposible compilar el código. Este es el error devuelto por el compilador:
Servo \ Servo.cpp.o: en la función '__vector_32': C: \ Archivos de programa (x86) \ Arduino \ bibliotecas \ Servo / Servo.cpp: 110: definición múltiple de '__vector_32' AccelPart1_35.cpp.o: C: \ Archivos de programa (x86) \ Arduino / AccelPart1_35.ino: 457: primero definido aquí c: / archivos de programa (x86) / arduino / hardware / tools / avr / bin /../ lib / gcc / avr / 4.3.2 /. ./../../../avr/bin/ld.exe: desactivación de la relajación: no funcionará con varias definiciones
El código
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 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3A);
// enable global interrupts:
sei();
}
void loop()
{
// Print every second the number of ISR invoked -> 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
}
¿Cómo resolver el conflicto con la servo biblioteca?
SOLUCIÓN
Conflicto resuelto usando el siguiente código. Se compila pero el contador asociado con el temporizador de 800Hz no incrementa su valor.
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 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << 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++;
}
Como el problema principal se ha resuelto, he creado otra pregunta aquí relacionada con el problema del incremento de contador.
#define _useTimer3
línea, o intenta poner un #undef _useTimer3
derecho después de la inclusión.