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 ) {
}
}