Timer 2 OVF Probleme

Hallo Community,
ich verzweifel hier gerade und ich hoffe ihr könnt mir helfen:)

ich würde gerne delay unabhängig mit dem Timer 2 eine Zeit von 5 Minuten abfragen und habe mir das Soweit auch alles berechnet.
Jedoch beim übertragen und Test weise ausprobieren ist mir aufgefallen das mein 16bit Zählregister schon nach millisekunden voll ist obwohl ich ein Prescale von 1024 eingesllt habe:(

Ich bin nun seit Stunden dran und finde den Feheler nicht.

volatile uint16_t ovf_timer2=0;

void setup() {
TCCR2B |= (1 << CS22) | (1 << CS20); // Set CS02 and CS00 bits for 1:1024 prescaler
sei();
Serial.begin(9600);
TCNT2 = 0; // set counter value to 0
TIMSK2 |= (1 << TOIE2); // enable timer overflow interrupt;
}

void loop() {
Serial.println(ovf_timer2);
if(ovf_timer2>18310){
ovf_timer2=0;}

}
ISR(TIMER2_OVF_vect)
{
ovf_timer2++; //FCPU/1024=15.625 → Schritte pro sekunde
TCNT2=0; // 15.625*300s=4.687.500 Schritte in 5 minuten
// 4.687.500/256= ca. 18.310 OVF in 5 minuten
}

das Hier ist mein vorläufiges Testprogramm auf dem Seriellen Monitor rauscht der Wert extream hoch obwohl laut rechnung nach 5 min ein wert von 18310 erreicht werden sollte.

Du musst die ganzen Timer-Register vorher auf 0 setzen. Auf dem Arduino sind alle Timer für PWM vorkonfiguriert. Das ist kein nackter Prozessor!

Außerdem musst du auf Multi-Byte Variablen außerhalb der ISR atomar zugreifen. d.h. bei abgeschalteten Interrupts

TCNT2 in der ISR auf 0 zu setzen ist überflüssig

Serenifly:
Du musst die ganzen Timer-Register vorher auf 0 setzen. Auf dem Arduino sind alle Timer für PWM vorkonfiguriert. Das ist kein nackter Prozessor!

Außerdem musst du auf Multi-Byte Variablen außerhalb der ISR atomar zugreifen. d.h. bei abgeschalteten Interrupts

TCNT2 in der ISR auf 0 zu setzen ist überflüssig

Danke das hat schonmal geholfen:) jedoch lande ich immer noch nicht bei 5 min ehr so ca. bei einer Minute. Habe ich etwas falsch berechnet?

Was sind multi-Byte Variablen?
meinst du damit das ich volatile uint16_t ovf_timer2=0; nur nach cli(); abfragen darf?

Wieso geht millis() nicht?

In meinem Hauptprogramm später habe ich mehrere Zeiten die voneinander abhängen.
Ich möchte alle 5 Minuten eine Messung durchführen aber das Hauptprogramm soll weiter abreiten im normalen Zyklus.
Beim delay hält das Programm ja an ist das bei millis(); anders?

Vergiss das mit dem Timer und schau dir das BlinkWithoutDelay Beispiel an

Serenifly:
Vergiss das mit dem Timer und schau dir das BlinkWithoutDelay Beispiel an

Dem stimme ich unumwunden zu.

Zu den anderen Fragen:

#include <util/atomic.h>
#define CriticalSection ATOMIC_BLOCK(ATOMIC_RESTORESTATE)

/*
 * FCPU/1024=15.625 -> Schritte pro sekunde
 * 15.625*300s=4.687.500 Schritte in 5 minuten
 * 4.687.500/256= ca. 18.310 OVF in 5 minuten
 */

volatile uint16_t ovf_timer2=0;

void setup() 
{
    Serial.begin(9600);
    CriticalSection
    {
      TCCR2A = 0;
      TCCR2B = _BV(CS22)|_BV(CS21)|_BV(CS20);
      TCNT2  = 0; // set counter value to 0  
      TIMSK2 = _BV(TOIE2); // enable timer overflow interrupt;
    }
}

void loop() 
{
  bool fiveMinutes = false;
  uint16_t merker;
  
  CriticalSection
  {
     if(ovf_timer2 >= 18310U)
     {
       ovf_timer2  = 0;
       fiveMinutes = true;
     }
     merker = ovf_timer2;
  }
  
  if(fiveMinutes) 
  { 
    Serial.print(millis()); 
    Serial.println("  5 Minuten um");
  }
 // Serial.println(merker);
}


ISR(TIMER2_OVF_vect)
{
  ovf_timer2++;                                         
}

Und, die Alternative im meinem Stil:

#include <CombieTimer.h>

Combie::Timer::Pulsator puls(5UL * 60UL * 1000UL);

void setup() 
{
    Serial.begin(9600);
    puls.start(); // mit Pause beginnen
}

void loop() 
{
  if(puls) 
  { 
    // hier Messung starten
    Serial.print(millis()); 
    Serial.println("  5 Minuten um");
  }
}

CombieLib.zip (50.9 KB)

Millis() blockiert nicht. Man kann natürlich mit millis() auch blockierend programmieren :wink: aber normalerweise macht man das nicht.

Millis zählt die Millisekunden seit dem Einschalten. Für Zeitmessungen oder Wartezeiten wird nur die Differenz zwiscehn der Anfangszeit und der Jetztzeit verglichen. Ich die Differenz größer als die Sollzeit kannst Du etwas machen. So ist eine Wartezeit nicht blockierend und Du kannst viele Dinge "gleichzeitig" machen zB mehrere LED unterschiedlich schnell blinken; Tastet Kontrollieren ob sie kurz oder lange gedrückt wurden usw.

Grüße Uwe