El temporizador AVR no funciona tan rápido cuando se cambia el número de PIN que se encienden o apagan

Estoy siguiendo el tutorial sobre fanáticos de AVR en Timers escrito por @Dean Camera . Su código dice:

#include <avr/io.h> 

int main (void) 
{ 
   DDRB |= (1 << 0); // Set LED as output 

   // TODO: Set up timer at Fcpu/64 

   for (;;) 
   { 
      // Check timer value in if statement, true when count matches 1 second 
      if (TCNT1 >= 15624) 
      { 
         PORTB ^= (1 << 0); // Toggle the LED 

         TCNT1 = 0; // Reset timer value 
      } 
   } 
}

Esto hace parpadear un LED. Edité el código para encender y apagar todos los pines en PORTB pero mi código "funciona más lento", y los LED parecen menos brillantes. Mi código:

#include <avr/io.h>

int main(){
    DDRB= 0xFF;

    TCCR1B |= (1<<CS10) | (1 << CS11);

    PORTB = 0xFF;
for (;;) {
    if(TCNT1 >= 15624){
        PORTB = 0x00;
        TCNT1 = 0;
    } else {
        PORTB = 0xFF;
    }
    }
}

¿Alguien puede explicar por qué sucede esto? También hay una mejor manera de encender/apagar los pines, esta es la única forma que se me ocurrió. Solo estoy ejecutando esto en un STK500 con un mega 16L.

Podría valer la pena usar su nombre para que reciba una alerta @Dean Camera
No pensé que funcionaría en preguntas, pero lo intentaré.
¿Puedes describir cómo estás conectando estos LED y qué chip avr estás usando?
@Jon No lo sé, esto se debe a que estoy usando la placa de desarrollo STK500, así que solo tengo que conectar un cable de puente a los LED. Estoy usando un mega16L. También haría una diferencia, ya que con el código original funciona como debería, "se ralentiza" con la misma configuración simplemente usando todos los pines que ejecutan mi código.

Respuestas (1)

A juzgar por su código, está haciendo lo siguiente:

Configurar temporizador.

Iniciar ciclo: ¿Está el temporizador en (o más de) un segundo? Sí: apaga los LED, restablece el temporizador No: enciende los LED. Repetir bucle.

Esto significa que los LED están encendidos durante todo el conteo del temporizador, luego se apagan en 1 segundo. Luego se vuelven a encender inmediatamente porque el temporizador ya no es >= 1 segundo.

En el ejemplo original PORTB ^= (1 << 0); // Toggle the LEDenciende el LED si está apagado, o lo apaga si está encendido. Lo que deberías estar haciendo es algo como:

for (;;) {
    if(TCNT1 >= 15624){
        PORTB = ~PORTB;
        TCNT1 = 0;
    }
}

(No he probado este código, pero la teoría es sólida)

Cada segundo que pasa, el temporizador se reinicia y los LED se invierten. Puede precargar PORTB con un valor, y cualquier LED que esté apagado se encenderá, y cualquiera que esté encendido se apagará.

Ahh sí, lo siento, estoy cansado y tratando de relajarme después de un duro día de repaso de matemáticas. Y tratar de editar el código terminó con un BSOD en Windows 7:/.
@Dean ¿No te encanta Windows? Es por eso que trabajo casi exclusivamente en Linux en estos días;)
Eso ha hecho el truco. Y no, me encanta Linux, pero no puedo molestarme en configurar un IDE para el desarrollo de AVR cuando hay un sistema estándar en Windows que es compatible con atmel, así que solo uso eso.
Makefiles y Emacs. Todo el IDE que necesitarás. ;-)
Emac? ¡Blaugh! Hinchado! Vi por siempre! (y eso es VI, no VIM)