Timer0 Overflow Interrupt funktioniert nicht auf ATtiny10

Ich versuche, den Timer0-Überlauf-Interrupt zu verwenden, um ein kleines Projekt zu erstellen. Ich habe einen solchen Timer im ATtiny45 verwendet und es hat funktioniert, aber mit ATtiny10 kein Ergebnis.

Also habe ich ein einfaches LED-Blinkprogramm ausprobiert und selbst das hat nicht funktioniert.

Hier ist der einfache Code:

#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;
}

Hoffe jemand kann mir helfen. Danke!

EDIT1:

Ich habe die Linie gewechselt

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

zu Linie

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

in meinem Code, um alle 0,524 Sekunden einen Überlauf zu erreichen. Aber die LED blinkt überhaupt nicht.

EDIT2:

Hier ist die Größe:

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

EDIT3:

Ich habe meine if-Anweisung im Wesentlichen wie folgt geändert:

int main(void){

  ...

  TCCR0B = (1 << CS01);

  ...

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

Jetzt blinkt meine LED alle 0,524 Sekunden, wie es sollte!

Also stimmt etwas mit meiner flüchtigen unit16_t Variablen overflow_val nicht . Ich habe es nicht nur direkt auf Hardware getestet, sondern auch eine Simulation mit atmelstudio durchgeführt. Auch in der Simulation tritt das Programm nie in die if-Anweisung ein, wenn ich die Variable overflow_val zum Umschalten der LED verwende.

BEARBEITEN 4

Ich glaube, irgendwas stimmt mit meiner ISR fkt nicht. Ich habe den folgenden Code getestet und die LED nie eingeschaltet.

#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;
}

Ich weiß nicht, was falsch ist.

Wenn ich in der While(1) -Schleife den Status des Zählerregisters TCNT0 überprüfe, funktioniert es. Der Zähler läuft also wie vorgesehen über, tritt aber bei einem Überlaufereignis niemals in die ISR(TIMER0_OVF_vect) -Funktion ein.

Zu wenig RAM, um Interrupts in C zu verwenden. Posten Sie, was avr-size auf Ihrem Elf anzeigt. Besonders die Daten- und BSS-Abschnitte.
Verlinken Sie die Startdatei crttn10.o?
Bist du sicher, dass du lange genug gewartet hast? Dies sieht so aus, als würde es etwa 67 Sekunden dauern, bis es überläuft. google.com/…
Ich bin kein AVR-Typ, aber ich vermute, dass Sie Interrupts global aktivieren müssen -- avrfreaks.net/forum/tut-newbies-guide-avr-interrupts?page=all
@ScottSeidman der sei();Anruf macht das.
Ich habe jetzt die Größe in meinem Kommentar hinzugefügt. Ich habe meinen Prescaler gewechselt. Ich verwende sei(), um die Interrupts global zu aktivieren. LED funktioniert nicht.
Ups, verpasst. Ich habe gezielt danach gesucht und es nicht gesehen!
jemand eine andere Idee, warum es nicht funktioniert?

Antworten (2)

Ich habe meinen Fehler gefunden. Ich benutzte:

ISR(TIMER0_OVF_vect){. . .}

anstatt

ISR(TIM0_OVF_vect){. . .}

Jetzt funktioniert es! Beim Überlauf von Timer0 wird die Interrupt-Routine ausgeführt. Vielen Dank für Ihre Hilfe

Es kann ähnlich aussehen, aber ATtiny45 Timer/Counter0 ist 8-Bit (es muss bis 256 + 1 für den Überlauf zählen), so dass der Prescaler 1024 beispielsweise beim Warten auf den Überlauf-Interrupt bei CLK = 1 MHz etwa 0,26 Sekunden benötigt.
ATtiny10 Timer/Counter0 ist 16-Bit (zählt bis 65536). Für die gleichen Einstellungen wie oben (1 MHz Takt, Prescaler 1024) gibt es 256 mal 0,26 Sekunden = fast 67 Sekunden bis zum Überlauf (wie von Bigjosh erwähnt).

Hallo, ich habe jetzt den Vorteiler geändert, um clk/8 mit der Zeile TCCR0B = (1 << CS01) zu haben; Also habe ich alle 0,524 Sekunden einen Überlauf. Aber ich kann die LED nicht blinken sehen.