Calcular cuántas veces se desbordará TIMER1

0

Estoy tratando de entender cómo configurar una interrupción de desbordamiento en ATmega328 TIMER1 para medir una frecuencia.

Estoy alimentando el pin PD4, que es donde TIMER1 está sincronizado externamente, con una onda cuadrada de 503kHz (4.8Vpp).

Dado que TIMER1 es de 16 bits, asumo que se desbordaría 7 veces por segundo. Mi razonamiento es el siguiente:

$$ number \; of \; overflows = \ frac {f} {TIMER1 \; max \; count} = \ frac {503,000Hz} {65,536} = 7.67 $$

Sin embargo, mi programa cuenta con 988 desbordamientos en su lugar. Eso es 128 veces más de lo que esperaba. ¿Por qué ??

Estoy usando el siguiente código:

volatile unsigned long int running;

ISR(TIMER1_OVF_vect) {
  running++;
}

void setup()
{
  Serial.begin(9600);

  // set up the 16 bit timer as an external frequency counter:
  TCCR1B |= (1 << CS10)|(1 << CS11)|(1 << CS12); // External clock, rising edge
  TIMSK1 |= (1 << TOIE1); // Enable overflow interrupt

  sei();  // enable global interrupts
}

void loop() {
  running = 0;
  delay(1000); // wait 1000ms
  Serial.println(running);
}

A continuación se muestra la señal del reloj externo en el alcance:

Elesquemaqueestoyusandoeselsiguiente.Elinductores220uHenlugarde68uH.

    
pregunta Ricardo

2 respuestas

0

Gracias al comentario de Mewa, que copio a continuación, descubrí cuál era el problema.

  

Consulte la Tabla 16-4 en la hoja de datos de su micro, y asegúrese de estar en Modo normal . De lo contrario, la bandera de desbordamiento podría activarse por otras razones.

De alguna manera, en mi entorno de programación, el TCCR1A se establece inicialmente en 1 y no en 0 como asumí.

Verifiqué y solucioné el problema con las siguientes líneas:

  Serial.println(TCCR1A); // <- this line outputs 1
  TCCR1A = 0; // <- this line fixed the problem - I now get 7 to 8 overflows per second
  TCCR1B |= (1 << CS10)|(1 << CS11)|(1 << CS12); 
  TIMSK1 |= (1 << TOIE1);

Si lo comprendo correctamente, significa que el bit WGM10 está configurado como 1 , configurando mi TIMER1 en Modo 1 (PWM, Fase Correcta, 8 bits) en lugar del Modo 0 deseado (Normal). El resultado fue que el temporizador se desbordó en 511 y no en 65535 como supuse.

¡Gracias a todos ustedes que me ayudaron a resolver esto!

    
respondido por el Ricardo
1

Según la página 140 de la hoja de datos la marca que se debe borrar se llama \ $ \ mathtt {TOV1 } \ $ y es el LSB del registro \ $ \ mathtt {TIFR1} \ $. Ese bit debería borrarse automáticamente, pero esa característica podría estar deshabilitada para usar interrupciones anidadas, lo que parece ser el caso para mí. Habría esperado un valor más alto para correr, pero ese es un int y podría ser de 8 bits de ancho, por lo que se desborda como loco (¡incluso está firmado!).

Intente agregar esta línea como la primera cosa en su ISR de desbordamiento:

TIFR1 &= 0x01;

Tal vez algo como:

TIFR1 &= 1 << TOV1;

funcionará también, pero quién sabe? Usted debe sumergirse en los encabezados. Prueba la primera solución, que debería funcionar.

    
respondido por el Vladimir Cravero

Lea otras preguntas en las etiquetas