ATtiny45 Timer1 reloj mal configurado

3

Estoy pasando por alto algo con un programa muy simple para mi ATtiny45 . Un programa que divide el reloj del sistema de 16 MHz por 16 y genera salidas en el pin 5 (OC0A) usando Timer0 y en el pin 6 (OC1A) usando Timer1.

El Pin 5 (Timer0) funciona como se esperaba, mido 1MHz.

Timer1 debe configurarse de manera similar, haciendo que el pin 6 (OC1A) cambie a la misma frecuencia de 1MHz, pero de alguna manera esto no funciona como se esperaba.

Pin 6 (Timer1) lleva 32kHz. Incluso cuando cambio el valor de OCR1A , la frecuencia permanece en 32kHz.

Sé que estoy pasando por alto algo aquí, pero no puedo entenderlo.

Aquí está el código fuente que uso:

#include <avr/io.h>

#define _BS(bit) ( 1 << ( bit ) )
#define _BC(bit) ( 0 << ( bit ) )

/*
 * 1 PB5 !RESET
 * 2 PB3 XTAL1
 * 3 PB4 XTAL2
 * 4 GND
 *
 * 8 VCC
 * 7 PB2      SCK
 * 6 PB1 OC1A MISO
 * 5 PB0 OC0A MOSI
 */

void setup( void ) {
        /*
         * Setup timer0 for divide by 16 from system clock
         */
        TCCR0A =                                                // Timer/Counter Control Register A
                _BC( COM0A1 ) | _BS( COM0A0 ) |                 // COM0A[1:0]  = 01   - Toggle output pin on every match.
                _BS( WGM01 )  | _BC( WGM00 );                   // WGM0[1:0]   = 10   - Clear timer on Compare Match (Auto Reload)
        TCCR0B =                                                // Timer/Counter Control Register B
                _BC( WGM02 )  |                                 // WGM0[2]     =  0   - Clear timer on Compare Match (Auto Reload)
                _BC( CS02 )   | _BC( CS01 )  | _BS( CS00 );     // CS0[2:0]    = 001  - System clock, no prescaler.
        OCR0A  =                                                // Timer/Counter0 Output Compare Register A
                ( 16 >> 1 ) - 1;                                // System clock divider. The OC pin toggles on each match introducing an extra factor 2.
        TCNT0  =                                                // Timer/Counter0 
                0;                                              // Initialize counter to 0.

        /*
         * Setup timer1 for divide by 16 from system clock
         */
        TCCR1 =                                                 // Timer/Counter Control Register
                _BS( CTC1 )   |                                 // Clear Timer on Compare match
                _BC( COM1A1 ) | _BS( COM1A0 ) |                 // COM1A[1:0]  = 01   - Toggle output pin on every match.
                _BC( CS13 )   | _BC( CS12 )   |                 // CS1[3:0]    = 0001 - System clock, no prescaler.
                _BC( CS11 )   | _BS( CS10 );
        OCR1A =                                                 // Timer/Counter1 Output Compare Register A
                ( 16 >> 1 ) - 1;                                // System clock divider. The OC pin toggles on each match introducing an extra factor 2.
        TCNT1 =                                                 // Timer/Counter1
                0;                                              // Initialize couter to 0.
        /*
         * Enable output drivers
         */
        DDRB =                                                  // Data Direction Register B
                _BS( PB1 ) |                                    // Enable output driver for PB1/OC1A
                _BS( PB0 );                                     // Enable output driver for PB0/OC0A
}

int main( void ) {
        setup();
        while ( 1 ) {
        }
}
    
pregunta jippie

1 respuesta

1

Debe configurar el temporizador 1 para CTC, establecer OCR1C en el valor máximo que desee para él y luego establecer OCR1A en el valor de coincidencia.

TCCR1 |= (
  _BV(CTC1) |   // CTC on OCR1C,
  _BV(CS12)     // System clock/8
); 
OCR1C = 2;      // Clear every 2 periods
OCR1A = 1;      // Match every 1st period

Establezca otros bits según sea necesario para la aplicación.

    
respondido por el Ignacio Vazquez-Abrams

Lea otras preguntas en las etiquetas