AVR - ATmega16 - Configuración del temporizador

3

Intentando averiguar la configuración del temporizador en Atmel Studio 6 para un microcontrolador ATmega16. Y simplemente no lo entiendo. Intento crear un TickCount similar a GetTickCount () Recupera la cantidad de milisegundos que han transcurrido desde que se inició el sistema, hasta 49.7 días.

El código se ve así:

#define F_CPU 8000000UL                         // 8MHz - prevents default 1MHz
// *** timer code necessary for handling lost coms, use volatile when variable is accessed from interrupts
volatile unsigned long TickCountSys;            // Number of milliseconds that have elapsed since the system was started.
volatile unsigned long TickCountComs;           // TickCountForLastComs
volatile unsigned long TCNT0_overflow_count = 0;

ISR(USART_RXC_vect) {
    TickCountComs = TickCountSys;               // Milliseconds since system started when received something.
    //blah blah
}

void timer_init() {
    TIMSK=(1<<TOIE0);                           // Enable timer overflow interrupt for timer0
    TCNT0=0x00;                                 // Set timer0 counter initial value to 0
    TCCR0 = (1<<CS00);                          // Start timer0 without prescaler
}

ISR(TIMER0_OVF_vect) {
    TickCountSys++;
}

int main(void) {
    timer_init();
    DDRC = 0xff;                                // Set all pins on PORTC for output
    sei();
    unsigned long TickCountENQ;                 // Tick count for sending enquiry character, 05dec, ^E
    char coms = 0;
    char ignore_coms = 0;
    while(1) {
        coms = (TickCountSys < TickCountComs + 50);
        if (TickCountSys > TickCountENQ + 25) {
            TickCountENQ = TickCountSys;
            // If not ignore coms, that is need coms, and has coms, i.e. has not lost coms, then send new Enquiry char every 25 ms
            // It stops asking for coms if coms is lost, and does nothing until new command received and then starts syncing again
            if (!ignore_coms && coms) USARTWriteChar(0x05);
        }
        if (!coms && !ignore_coms) {            // If not coms and not ignoring lost coms then stop all movement
            PORTC = 0x00;
        }
        //blah blah...
    }
}

Herramientas - > Programación de dispositivos - > Fuses dice:

BODLEVEL    4V0
SUT_CKSEL   EXTMEDFXTALRES_16KCK_64MS

Por lo que sé, esta es la configuración correcta (se entregó de esa manera). Hay algo que no entiendo al leer los tutoriales de temporizador.

EDITAR: ¿Qué debo hacer para que TickCountSys aumente una vez cada milisegundos y proporcione la cantidad de milisegundos que han transcurrido desde que se inició el sistema?

    
pregunta wittrup

1 respuesta

2

I am trying to create a TickCount.

Necesitará una variable global (lo suficientemente grande) para mantener la cantidad de segundos (49.7 * 24 * 60 * 60 * 1000 = valor de 32 bits de largo O un ulong) transcurridos, incrementarlo dentro de su isr (parece que sí lo hizo esta parte derecha!).

volatile uint32_t elapsed_ms;

entonces necesitarás una función que devuelva este valor.

uint32_t TickCount(void){
 return elapsed_ms;
}

Ahora llegamos a la segunda parte:
TickCountSys increases once every milli second

Si desea hacerlo con 8MHz Xtal + Timer 0 Overflow , no puede lograr ticks precisos de 1 ms. El motivo es 8000 pulsos de reloj no pueden desbordar el temporizador 0 . Si no usas preescala, entonces T0 se desborda = 8000/256 = 31.25 veces. Si realiza una escala previa del reloj del temporizador con la configuración T / 8, entonces 1000/256 = 3.90625 cerca de 4 desbordamientos.

Suponiendo que eligió seguir adelante con el pre-escalar T / 8, entonces tendrá que modificar el cuerpo de ISR a algo como

      static uint8_t temp_count=0;
        temp_count++;
      if(temp_count >= 4){
        temp_count = 0;
        elapsed_ms++;
        //add a method here to roll the 49.7 day completion.
      }

Eso es todo.
Desde tu código parece que has hecho los ajustes de temporizador e interrupción correctamente. Pero su código es bastante confuso y no pude localizar ninguna función llamada TickCount o similar.

Le sugiero que comience con un código simple, como parpadear un led en el desbordamiento del timer0 (con un valor de ALTA PRESCALAR como T / 1024). Luego agregue gradualmente la lógica del código. Buena suerte.

    
respondido por el vvy

Lea otras preguntas en las etiquetas