temporizador AVR: modo CTC

0

Tengo algunos problemas para entender los temporizadores en AVR, especialmente el modo CTC

En el modo CTC, cuando se produce una coincidencia, puedo alternar los pines OC1A o OC1B.

Según la hoja de datos

  

En el temporizador de borrado en modo de comparación o CTC (WGM13: 0 = 4 o 12), el registro OCR1A o ICR1 se utiliza para manipular el   resolución contraria. En el modo CTC, el contador se borra a cero cuando el valor del contador (TCNT1) coincide con el OCR1A   (WGM13: 0 = 4) o el ICR1 (WGM13: 0 = 12). El OCR1A o el ICR1 definen el valor superior para el contador, por lo que también   resolución

Lo que pensé era que OC1A cambiaba cuando TCNT1 == OCR1A y OC1B cambiaba cuando TCNT1 == OCR1B  Pero después de leer la hoja de datos, ¿no creo que OCR1B tenga algún rol en el modo CTC?

y el código siguiente no funciona

#include <avr/io.h>                        // Defines pins, ports, etc
#define F_CPU 1000000UL

#define LED1 PB1
#define LED2 PB2
#define LED_PORT PORTB
#define LED_DDR DDRB

static inline void initTimer(void) {
    TCCR1B |= (1 << WGM12);                                  // CTC mode
    TCCR1A |= (1 << COM1B0);             // Toggles OC1B pin each cycle through
    TCCR1B |= (1 << CS10) | (1 << CS11);               // CPU clock / 64, 15625 tick every Sec
}

int main(void) {
    // -------- Inits --------- //
    initTimer();
    LED_DDR |= (1 << LED1);
    LED_DDR |= (1 << LED2);

    //OCR1A = 15625;                        // around 1000ms delay
    OCR1B = 15625;  

    // ------ Event loop ------ //
    while (1) {

    }                                                   //End event loop
    return 0;                            // This line is never reached
}

Incluso cuando lo intenté con la interrupción, no pude cambiar un pin basado en OCR1B

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

// initialize timer, interrupt and variable
void timer1_init()
{
    // set up timer with prescaler = 64 and CTC mode
    TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);

    TIMSK1 |= (1 << OCIE1B);        // Output Compare B Match Interrupt Enable
    // initialize counter
    TCNT1 = 0;

    // initialize compare value
    OCR1B = 7812;
    sei();
}


ISR(TIMER1_COMPB_vect) { 
    PORTC ^= (1 << 0);
}

int main(void)
{
    // connect led to pin PC0
    DDRC = 0XFF;

    // initialize timer
    timer1_init();

    // loop forever
    while(1)
    {

    }
}

Pero es posible con OCR1A

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

// initialize timer, interrupt and variable
void timer1_init()
{
    // set up timer with prescaler = 64 and CTC mode
    TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);

    TIMSK1 |= (1 << OCIE1A);        // Output Compare A Match Interrupt Enable
    // initialize counter
    TCNT1 = 0;

    // initialize compare value
    OCR1A = 15625;
    sei();
}

ISR(TIMER1_COMPA_vect) {
    PORTC ^= (1 << 1);
}


int main(void)
{
    // connect led to pin PC0
    DDRC = 0XFF;

    // initialize timer
    timer1_init();

    // loop forever
    while(1)
    {

    }
}

¿Es posible alternar con OCR1B? ¿Cómo puedo alternar dos pines con diferente retraso en el modo CTC?

EDITAR:

#include <avr/io.h>                        // Defines pins, ports, etc
#define F_CPU 1000000UL

#define LED1 PB1
#define LED2 PB2
#define LED_PORT PORTB
#define LED_DDR DDRB

static inline void initTimer(void) {
    TCCR1B |= (1 << WGM12);                                  // CTC mode
    TCCR1A |= (1 << COM1A0);           // Toggles OC1A pin each cycle through
    TCCR1A |= (1 << COM1B0);           // Toggles OC1B pin each cycle through
    TCCR1B |= (1 << CS10) | (1 << CS11);               // CPU clock / 64, 15625 tick every Sec
}

int main(void) {
    // -------- Inits --------- //
    initTimer();
    LED_DDR |= (1 << LED1);
    LED_DDR |= (1 << LED2);

    OCR1A = 15624;                        // around 1000ms delay
    //OCR1B = 7812;

    // ------ Event loop ------ //
    while (1) {

    }                                                   //End event loop
    return 0;                            // This line is never reached
}

Bueno, OCRxB no juega un papel en el modo CTC. En el programa anterior, dado que el TCCR1A está configurado para alternar cuando se produce una coincidencia con OCR1A, dos LED se alternan como se supone, pero alternativamente con un retraso de 1 seg. ¿Por qué?

Digamos que introduje OCR1B en el código y lo puse en OCR1B = 7812. Pero cuando ejecuto el programa, pude ver claramente una diferencia en el patrón de parpadeo. ¿Por qué?

    
pregunta Athul

0 respuestas

Lea otras preguntas en las etiquetas