atmega32u4 configurar el contador en modo CTC

1

como se señaló en el hilo: atmega32u4 use Timer como fuente para un contador

Intenté usar el reloj generado del temporizador 4 como entrada para un contador1 y counter1 debería activar el evento de comparación de partidos después de 42 ciclos de reloj.

Pero no soy capaz de alcanzar el comportamiento deseado. Aquí hay un pequeño código de prueba:

#include "Arduino.h"

#define CLOCKPIN 12
#define DEBUGPIN 19

//#define USE_A

// generate 1 MHz from 8 MHz
#define CLOCKCYCLE 3

// UPDATE
#ifdef USE_A
ISR(TIMER1_COMPA_vect) {
#else
ISR(TIMER1_COMPB_vect) {
#endif
    digitalWrite(DEBUGPIN,HIGH);
    digitalWrite(DEBUGPIN,LOW);
}

void setup()
{

    // set up pins
    pinMode(CLOCKPIN, OUTPUT);
    pinMode(DEBUGPIN, OUTPUT);

//--------------------- generate clock -------------------
    // reset timer4
    OCR4C = 0;
    OCR4D = 0;

    TCCR4A = 0x00;
    TCCR4B = 0x00;
    TCCR4C = 0x00;
    TCCR4D = 0x00;

    TCNT4=0;

    // Toggle OC4D on Compare Match | enable PWM
    TCCR4C = _BV(COM4D0) | _BV(PWM4D);


    // Clear Timer on Compare Match
    TCCR4D = _BV(WGM41);

    // set lock bit for sync update
    TCCR4E = _BV(TLOCK4);

    // Set compare value
    OCR4C = CLOCKCYCLE*2;
    OCR4D = CLOCKCYCLE;

    // No prescaling
    TCCR4B = _BV(CS10);

//--------------------- setup counter -------------------

     //reset timer
    TCNT1 = 0;

    // disable
    TCCR1A = 0;
    TCCR1B = 0;

    // clear interrupt flags
    TIFR1 = _BV(OCF1A) | _BV(OCF1B);


    // trigger on falling edge of T1
    TCCR1B = _BV(CS12) | _BV(CS11) | _BV(CS10) | _BV(WGM12);


#ifdef USE_A
    // interrupt on every 42. cycle
    OCR1A = 42;

    // turn on compare A interrupt.
    TIMSK1 = _BV(OCIE1A);
#else
    // interrupt on every 42. cycle
    OCR1B = 42;

    // turn on compare B interrupt.
    TIMSK1 = _BV(OCIE1B);
#endif
}

el bucle está vacío.

Con define USE_A obtengo la siguiente forma de onda: lainterrupciónsedisparacada~66200µssuenacomoeldesbordamientodelcontadorde16bits.

CondefinirUSE_Acomentado,obtuveelsiguienteresultadocableado: 219µsclockenelrelojde1180µs.Laúnicaideaquetengoparaestoesunreiniciooalgoasí.

¿Alguientieneunaideadeloqueestámalconmicódigodecontador?

ACTUALIZACIÓN:

SemodificólabanderaquefaltaylallamadaISR.AhoratieneelaspectodeUSE_Aasí: ¿La parte superior debería ahora establecerse en 42 y restablecerse en 0 después de que ocurrió la interrupción? Pero actualmente lleva casi el doble de tiempo ...

    
pregunta Steve

1 respuesta

2

Cuando comenta la línea USE_A , habilita la interrupción de comparación para el canal B en lugar del canal A. Como resultado, el vector de interrupción de comparación de coincidencia ahora es TIMER1_COMPB_vect .

Sin embargo, no ha definido un controlador de interrupción para esto, lo que significa que cuando se produce la coincidencia de comparación, la llamada de interrupción produce una excepción que hace que el programa se reinicie desde el vector de restablecimiento, por lo que verá que se restablece al mismo ritmo que cuando A era utilizado.

Para obtener una comparación de comparación cada 42 ciclos, debe usar el modo "CTC". Hay dos variantes para esto: la primera usa OCR1A como la comparación de comparación, y la otra usa ICR1 como la comparación de comparación. Cuando esté en el modo correcto, una coincidencia con uno de estos borrará automáticamente el contador.

Sin embargo, ha establecido TCCR1A y TCCR1B en 0, lo que a su vez establecerá que todos los bits WGM1x sean cero. Esto selecciona el modo de operación "Normal". En este modo, una comparación de comparación con OCR1A o OCR1B activará TIMER1_COMPA_vect y TIMER1_COMPB_vect respectivamente, pero no restablecerá el temporizador, lo que significa que debe contar hasta el final. en la parte superior (65535) y el desbordamiento entre cada comparación, por lo que las interrupciones se producen cada 65536 ciclos independientemente de lo que haya establecido el OCR1x registros.

Para usar OCR1A como la parte superior y hacer que interrumpa cada 42 relojes, debes configurar el modo correcto. Los modos se enumeran en Tabla 14-4 en la hoja de datos . El modo 4 es CTC con OCR1A como valor superior. Esto implica que necesita configurar el bit WGM12 en el registro TCCR1B para que sea un 1.

Con ese bit establecido, y OCR1A establecido en 42, debes obtener una interrupción cada 42 recuentos.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas