¿La hoja de datos del AVR ATmega32 está equivocada?

5

Actualmente estoy usando un ATmega32 para mantener el tiempo, así que leí cuidadosamente la hoja de datos y configuré el temporizador 1 para generar una interrupción cada segundo.

De acuerdo con la siguiente fórmula en la hoja de datos, utilizando un reloj de 16 MHz, un preescalador de 256 y OCR1A = 31249, debería obtener una frecuencia de 1 Hz en modo CTC:

\ $ f_ {OCnA} = \ frac {f_ {clk \ _I / O}} {2 \: \ cdot \: N \ cdot \: (1 \: + \: OCRnA)} \ $

Esta fórmula está disponible en la página 99 de la Hoja de datos de ATmega32 .

He configurado el temporizador 1 de la siguiente manera:

TCCR1A = 0;
TCCR1B = (1<<WGM12)|(1<<CS12);
OCR1A = 31249;
TIMSK = (1<<OCIE1A);

Aquí está el código de interrupción

ISR(TIMER1_COMPA_vect){
    sec++;
}

Luego, uso un LCD para imprimir continuamente el valor de sec , y obtengo un tiempo de 0.5 segundos. En otras palabras, por cada segundo que pasa, el temporizador genera dos interrupciones.

Al principio pensé que tal vez tenía mal los fusibles, pero no parece ser el caso, ya que los retrasos funcionan bien. De todos modos, así es como configuré los fusibles:

-U lfuse:w:0xff:m -U hfuse:w:0x99:m

No tengo la menor idea de lo que está sucediendo, he revisado todo nuevamente, probé otro ATmega32, probé otro oscilador de cristal de 16 MHz y todavía obtengo el mismo resultado.

¿Está mal la hoja de datos o me falta algo aquí?

    
pregunta Chi

2 respuestas

14

Si el reloj del sistema es 16 MHz y el prescaler es 256 , el temporizador se ejecutará en \ $ \ large \ frac {16 \, MHz} {256} = \ small 62500 \, Hz \ $, por lo que habrá un incremento en cada \ $ \ large \ frac {1} {62500 \, Hz} = \ small 16 \, \ mu s \ $. Se generará una interrupción cuando el valor del contador sea 31249 . Si calculamos este tiempo: \ $ \ small 16 \, \ mu s \ times 31250 \, ticks = 0.5 \, s \ $, que es exactamente el mismo resultado que tiene.

La ecuación en la hoja de datos es para un propósito diferente:

  

Para generar una salida de forma de onda en el modo \ $ \ small CTC \ $, la salida de \ $ \ small OC1A \ $ puede configurarse para alternar su nivel lógico en cada comparación de comparación configurando los bits del modo de comparación para cambiar al modo de alternancia \ $ \ small (COM1A1: 0 = 1) \ $. El valor \ $ \ small OC1A \ $ no será visible en el pin del puerto a menos que la dirección de los datos para el pin esté configurada para mostrar \ $ \ small (DDR_ {OC1A} = 1) \ $. La forma de onda generada tendrá una frecuencia máxima de \ $ \ small fOC1A = fclk_ {I / O} / 2 \ $ cuando \ $ \ small OCR1A \ $ se establece en cero \ $ (0x0000) \ $. La frecuencia de la forma de onda se define mediante la siguiente ecuación: (...)

Si medirías la frecuencia de un pin específico, creo que sería 1 Hz.

Para lograr un 1 s , \ $ \ small 16 \, \ mu s \ times 62500 = 1 \, s \ $ generación de interrupciones, necesita 62500 ticks y cuando el contador comienza desde 0, establezca OCR1A en \ $ \ small 31250 \ times 2 - 1 = 62499 \ $, y como Timer1 es un temporizador de 16 bits, este valor no es demasiado alto (< 65535, \ $ 2 ^ {16} -1 \ $ ).

    
respondido por el Bence Kaulics
5

Esa fórmula es para la frecuencia de salida del pin OCnA ("Para generar una salida de forma de onda en modo CTC, la salida OC1A puede configurarse para alternar su nivel lógico en cada comparación de comparación configurando los bits de modo de salida de comparación en modo alternar (COM1A1: 0 = 1). [...] La frecuencia de la forma de onda se define mediante la siguiente ecuación: "). Ya que estás usando la interrupción, recibirás dos comparaciones por período. Elimine los 2 del denominador para calcular la frecuencia de interrupción.

    
respondido por el Ignacio Vazquez-Abrams

Lea otras preguntas en las etiquetas