Problema de los temporizadores precalificados

1

Estoy usando un attiny2313a, y estoy teniendo muchos problemas para averiguar qué está pasando con el temporizador. Es muy simple, pero simplemente se niega a trabajar.

Tengo un reloj de 16Mhz. Cuando instalo un preescalador de 1024, el reloj TCNT1 aumentará en la frecuencia 16Mhz / 1024 = 0.0156MHz, lo que significa que obtengo un incremento cada 64uS.

Por lo tanto, por un segundo, debo esperar 1000000/64 = 15625

Esto está bien, porque TCNT1 es un contador de 16 bits.

Sin embargo, cuando configuro un programa de prueba, lo que recibo es un pitido muy largo en algún lugar más cercano a 15-16 segundos.

Cuando configuro el prescaler en 64, entonces 15624 me da exactamente un segundo.

En mi mente, mi cristal se está comportando como si esperara un cristal de 1Mhz. ¿Mi proceso de pensamiento es incorrecto, o hay algo más que podría estar equivocado?

Aquí está mi código de prueba, las partes importantes:

#include <avr/io.h>
#include <avr/interrupt.h>


#define Echo    PINB0
#define Trig    PINB1
#define Buzz    PINB4
#define Led PIND4

int main(void)
{
DDRD = (1<<Led);
PORTD = 1<<Led;

DDRB = 1<<Trig | 1<<Buzz;
DDRB &= ~(1<<Echo);


TCCR1B = (1<< CS10) |  (1<<CS12); // prescaler = 1024

    while(1) {      
        beep();
        wait(1);
    }
}

void wait(int t){
    TCNT1 = 0;
    while(TCNT1 <= 15624*t){

    }
}
void beep(){
    TCNT1 = 0;
    PORTB = 1<<Buzz;
    while(TCNT1 <= 15624){

    }
    PORTB &= ~(1<<Buzz);
}
    
pregunta triplebig

2 respuestas

1

Parece que su MCU se está ejecutando a 1MHz como describe alexan_e. Compruebe sus fusibles: seleccione el cristal externo como fuente de reloj y desactive el fusible CKDIV8.

Con respecto a tu código, lo estás haciendo mal. Debe utilizar interrupciones para detectar eventos de temporizador. En este caso particular, una interrupción de comparación de salida de salida.

Debe configurar su número mágico en OCR1A y configurar el bit OCIE1A en el registro TIMSK para habilitar la interrupción. No olvide proporcionar un controlador de interrupción de desbordamiento de timer1 en su código.

De esta manera, su código no se quedará atascado en bucle cerrado mientras el temporizador esté contando. Esa es la belleza de usar periféricos en MCU, ya que se están ejecutando en paralelo, mientras el temporizador está contando, el procesador puede hacer otras cosas útiles o ahorrar energía.

Tenga en cuenta que debe reiniciar el temporizador a 0 en el controlador de interrupciones o configurar el temporizador en modo CTC (bit WGM12 en TCCR1B)

    
respondido por el miceuz
1

La fuente de reloj predeterminada del microcontrolador es RC interno establecido en 8MHz.
El dispositivo también viene con el fusible CKDIV8 programado que divide el reloj entre 8 y los resultados a 1MHz que parece coincidir con lo que usted describe.

Una prueba simple que puede hacer es quitar el cristal y alimentar el circuito. Si el mcu funciona, entonces está usando el RC interno, por lo que necesita cambiar los fusibles para usar el cristal como fuente de reloj. Si no, entonces probablemente solo esté relacionado con el divisor de reloj.

Con respecto al divisor del reloj, lea mi respuesta aquí

    
respondido por el alexan_e

Lea otras preguntas en las etiquetas