Verständnisfragen

Guten Abend

Ich bin dabei von Bascom zu Arduino zu wechseln und habe mich ein wenig eingelesen und frage mich warum ich das nicht schon viel früher gemacht habe.

Trotzdem sind nun ein paar Fragen aufgetaucht.

Wichtig ist mir das Interrupt handling.

Bisher war ich der Meinung, dass die Interrupts nach Priorität abgearbeitet werden. Irgendwo steht aber, dass falls zwei Interrupts gleichzeitig auftreten nur der Erste Auftretende berücksichtigt wird.
Was stimmt nun?

Die zweite Frage bezieht sich auf die TimerInterrupts. In meinen Programmen verwende ich den Timer0 Interrupt als Taktgeber. Kann man diesen spezifisch Aktivieren? Und wenn Ja wie?

Grüsse aus der Schweiz

Christoph

Christoph62:
Irgendwo steht aber, dass falls zwei Interrupts gleichzeitig auftreten nur der Erste Auftretende berücksichtigt wird.

Das ist falsch. Jede Interrupt-Quelle setzt ein Interrupt Flag. Diese werden nach festen Prioritäten abgearbeitet. Wenn der erste Interrupt fertig ist, kommt erst mal ein normaler Prozessortakt dran, danach wird die nächste ISR aufgerufen. Das gilt auch für den Fall dass der zweite Interrupt auftritt während die ISR des ersten gerade läuft.

Interrupts gehen erst verloren wenn auf einem Interruptvektor mehr als ein Interrupt ausgelöst wird ohne dass diese bearbeitet werden, z.B. weil eine andere ISR zu viele Taktzyklen braucht.

In meinen Programmen verwende ich den Timer0 Interrupt als Taktgeber. Kann man diesen spezifisch Aktivieren?

Auf Timer0 läuft durch die Arduino Software schon ein Timer, der u.a. für millis() und delay() verwendet wird.

Das ging aber schnell, vielen Dank. Deine Antwort Hilft mir ein gutes Stück weiter.

Ok, ich kann die Funktion millis() oder micros() für den gleichen Zweck verwenden. Kann man diese Werte auf null Stellen (ohne Start des Programmes) ?

Gruss Christoph

Christoph62:
Ok, ich kann die Funktion millis() oder micros() für den gleichen Zweck verwenden. Kann man diese Werte auf null Stellen (ohne Start des Programmes) ?

Du kannst dir eine eigene Variable anlegen die einen millis() Wert speichert. Die kannst du dann auf 0 setzen.

Kann man diese Werte auf null Stellen (ohne Start des Programmes) ?

Ja!
Aber das macht keinen Sinn.

Das macht schon Sinn. Ich will erreichen, dass nach x Millisekunden etwas ausgeführt wird. Am einfachsten würde das so gehen:

If ( millisec() = x )
{
Irgendwas()
Millisec() = 0
}

Kann millisec() so einfach auf Null gesetzt werden?

mit if(millisec() = x) nicht. Ein Vergleich erfolgt mit ==

Schau dir die Blink Without Delay Beispiele an, und du wirst sehen, ein zurücksetzen ist nicht nötig und maxht weniger Sinn

Das macht schon Sinn.

Nein, tut es nicht!
Denn du machst dir die Zeitbasis für alle weiteren Aufgaben kaputt!
Keiner hat das bis jetzt hier gebraucht.
Und die, welche es wollten, haben eingesehen, dass es ein Irrweg ist.
Auch du wirst zu dieser Erkenntnis kommen.

Es gibt nur einen einzigen vernünftigen Grund die Zeitbasis zu manipulieren!
Und zwar, die Zeitkorrektur nach einem Sleep, oder anhand einer RTC.

Kann millisec() so einfach auf Null gesetzt werden?

So natürlich nicht!

Aber so:

#include <util/atomic.h>


extern volatile unsigned long timer0_millis;

void setup() 
{
 
}

void loop() 
{
   ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
   {
      timer0_millis = 0UL;
   }
}

Wie gesagt, es ist ein ganz dünnes Brett, auf welches du klettern willst.
Die Rache folgt auf dem Fuße.

Schau dir die Blink Without Delay Beispiele an

Volle Zustimmung.

Die bessere Variante:

#include <SimpleTimer.h>

const byte led = 13;
SimpleTimer timer;

void tuWas()
{
  digitalWrite(led,!digitalRead(led)) ; 
}


void setup() 
{
 pinMode(led,OUTPUT);
 timer.setInterval(1000,tuWas);
}

void loop() 
{
  timer.run();
}

Hallo Christoph,

nein, du willst nicht timer0_millis manipulieren,
du brauchst dir nur die jeweilige Startzeit ab der du messen/warten usw. willst, zu merken:

unsigned long start;
void loop() {

if (startbedingung) start= millis();

if ( millis() - start > INTERVALL ) {
   // Zeit abgelaufen, tu was
   
   start= millis();  // neu setzen 
   }


}

Wenn du es so machst ( Differenz jetzt - alt mit Dauer vergleichen), funktioniert das ganze "immer und ewig", auch wenn irgendwann (nach ca. 49 Tagen) der millis() - Zähler überläuft!

Das berühmte BlinkWithoutDelay solltest du verstanden haben.

Herzlichen Dank an alle !!!

Gruss

Christoph