La interrupción por desbordamiento del temporizador0 no funciona en ATtiny10

1

Estoy tratando de usar la interrupción de desbordamiento de Timer0 para hacer un pequeño proyecto. Utilicé un temporizador de este tipo en el ATtiny45 y funcionó, pero con ATtiny10 ningún resultado.

Así que probé un sencillo programa de parpadeo de LED e incluso eso no funcionó.

Aquí está el código simple:

#define F_CPU 1000000UL  // 1 MHz

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

volatile uint16_t overflow_val=0;

ISR (TIMER0_OVF_vect){
  overflow_val++;
}

int main(void){
  DDRB = (1<<PB1);
  // Timer0 normal mode
  TCCR0A = 0x00;
  // Start timer with presc 1:1024
  TCCR0B = (1<<CS02) | (1<<CS00);
  TCNT0 = 0;
  TIMSK0 |= (1 << TOIE0);
  sei();

  for(;;){  
    if(overflow_val >= 1)
        {
            if(TCNT0 >= 145){
                PORTB ^= (1 << PB1);
                TCNT0 = 0;
                overflow_val = 0;
            }
        }
  }
  return 0;
}

Espero que alguien me pueda ayudar. Gracias!

EDIT1:

He cambiado la línea

TCCR0B = (1<<CS02) | (1<<CS00);  

a la línea

TCCR0B = (1 << CS01);  // clk/8

en mi código para lograr un desbordamiento cada 0.524sec. Pero el LED no parpadea en absoluto.

EDIT2:

Aquí está el tamaño:

>avr-size test_attiny10_2.ino.elf
   text    data     bss     dec     hex filename
    138       0       2     140      8c test_attiny10_2.ino.elf

EDIT3:

Cambié mi declaración if en la página principal de la siguiente manera:

int main(void){

  ...

  TCCR0B = (1 << CS01);

  ...

  for(;;){
    if(TCNT0 >= 0xFFFE)
        {
                PORTB ^= (1 << PB1);
                TCNT0 = 0;
        }
  }
  return 0;
}

¡Ahora mi LED está parpadeando todos los 0.524 segundos como debería!

Entonces, algo está mal con mi variable unitable16_t variable overflow_val . No solo lo probé directamente en hardware, sino que también hice una simulación con atmelstudio. También en la simulación, el programa nunca ingresa la instrucción if si uso la variable overflow_val para encender el LED.

EDIT 4

Creo que algo no está bien con mi ISR fkt. Probé el siguiente código y nunca encendí el LED.

#define F_CPU 1000000UL  // 1 MHz

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

volatile uint8_t ovf_counter = 0;

void ioinit(void){
    // PB1->outputs
    DDRB = (1<<PB1);

    // Start timer with presc 1:64
    TCCR0B = (1<<CS01) | (1<<CS00);
    // Initialize counter Overflow at 0xFFFF
    TCNT0 = 0;

    // Enable global interrupts
    sei(); 
}

int main(void){
    ioinit();
    TIMSK0 |= (1<<TOIE0);
      while(1){        
        if(ovf_counter>=2){
          PORTB = (1<<PB1);
          ovf_counter=0;    
        }
      }
}

ISR(TIMER0_OVF_vect){
  ovf_counter++;
  TCNT0 = 0;
}

No sé qué está mal.

Si verifico en mientras (1) repite el estado del registro de contador TCNT0, funciona. Por lo tanto, el contador está desbordado como debería, pero nunca ingresa en un evento de desbordamiento la función ISR (TIMER0_OVF_vect) .

    
pregunta marsUbuntux

2 respuestas

1

Encontré mi error. Yo utilicé:

ISR(TIMER0_OVF_vect){. . .}

en lugar de

ISR(TIM0_OVF_vect){. . .}

¡Ahora funciona! En el desbordamiento del timer0 se ejecutará la rutina de interrupción. Gracias por tu ayuda

    
respondido por el marsUbuntux
1

Puede parecer similar, pero ATtiny45 Timer / Counter0 es de 8 bits (debe contar hasta 256 + 1 para el desbordamiento), así que por ejemplo, esperando una interrupción por desbordamiento cuando CLK = 1MHz, prescaler 1024 tomará aproximadamente 0.26 segundos. El temporizador / contador ATtiny10 0 es de 16 bits (cuenta hasta 65536). Para los mismos ajustes que el anterior (reloj de 1MHz, prescaler 1024) da 256 veces 0.26sec = casi 67 segundos para desbordar (como lo menciona bigjosh).

    
respondido por el smajli

Lea otras preguntas en las etiquetas