Verhalten MCU während Durchlauf einer If-Schleife bei eintreten eines Interrupt

Gast #3213819
Lesenswert?

Hallo zusammen,

ich programmiere gerade auf meinem ATmega1284p eine kleine Uhr.
Mir stellt sich jetzt jedoch die Frage, was eigentlich passiert, wenn 
der Mikrocontroller gerade eine If-Schleife bearbeitet und dabei ein 
Interrupt-Event eintritt. Eigentlich sollte doch der MCU alles quasi 
zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört 
hat.

ergibt es aus sicherheitsgründen sinn während den sehr wichtigen 
If-Schleifen, die Interrupt abzuschalten und danach wieder einzuschalten 
oder funktioniert das immer korrekt?

Beispiel:
1
if(day == 31 && ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && hour == 23 && minute == 59 && second == 59)
2
    {
3
      month++;
4
      second = 0;
5
      minute = 0;
6
      hour = 0;
7
      day = 1;
8
    }

Angenommen während er gerade die Variable minute auf 0 setzt, tritt ein 
Interruptevent ein. Läuft der Programmpointer danach wirklich bei hour = 
0 weiter?

Gruß

HeyHey
Gast #3213828
Lesenswert?

HeyHey schrieb:
> eine If-Schleife bearbeitet
Zeig mir mal bitte, wo in dem Beispiel eine Schleife sein soll.

HeyHey schrieb:
> Eigentlich sollte doch der MCU alles quasi
> zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört
> hat.
Der Controller macht da (außer PC) gar nichts von selber. Der Compiler 
kümmert sich zum Teil drum, wichtige Register zu sichern. Das ist aber 
meines Wissens nur das Status Register.
Gast #3213833
Lesenswert?

HeyHey schrieb:
> Hallo zusammen,
>
> wenn
> der Mikrocontroller gerade eine If-Schleife bearbeitet

Wirklich gefährlich wird es erst beim sogenannten
1
month++
Vergleich, bzw beim
1
second = 0;
Sprung!

Im schlimmsten Fall kann bei einer Polaritätsumkehr des Taktsignals 
ein Interrupt sich selbst unterbrechen.
Gast #3213837
Lesenswert?

Nein, das sollte der Compiler richtig machen, d.h. er sollte in der ISR 
alle Register sichern, die er verwendet.
Ausnahmen sind Zugriffe auf gemeinsame Variablen. Z.B. ISR ändert Zeit, 
während Hauptprogramm diese gerade verwendet.
Bei AVR-gcc gibt es dafür util/atomic.h. Damit kann man atomare, d.h. 
nicht unterbrechbare, Abschnitte definieren.
BTW, ist der 1284 groß genug für Deine Uhr?  ;-)
#3213880
Lesenswert?

@ HeyHey (Gast)

>der Mikrocontroller gerade eine If-Schleife bearbeitet

Gibt es nicht.

> und dabei ein
>Interrupt-Event eintritt. Eigentlich sollte doch der MCU alles quasi
>zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört
>hat.

Macht er auch.

>ergibt es aus sicherheitsgründen sinn während den sehr wichtigen
>If-Schleifen, die Interrupt abzuschalten

Ja, nennt sich atomarer Zugriff und ist im Artikel Interrupt 
beschrieben.

>und danach wieder einzuschalten
>oder funktioniert das immer korrekt?

Nein. Nur, wenn die Variablen NICHT in Hauptprogramm und im Interrupt 
verwendet werden.
Gast #3214189
Lesenswert?

Noch mal zur Uhr selber:
Eigentlich keiner speichert seine Uhrzeit in 6 Variablen (year, month, 
day, hour ...) ab und rechnet damit herum.
Sinnvoller ist es, die Zeit in nur einer Variablen abzubilden. Bei Unix 
z.B. Sekunden seit 1.1.1970. Bei MS gibt es etwas ähnliches ab 1900.
Nur zur Ausgabe werden dann Stunden, Minuten etc berechnet.
Das reduziert den Aufwand, dass man in der Interrupt-Routine dann diese 
vielen If-Vergleiche für unterschiedliche Monate und Schaltjahre hat.
#3214237
Lesenswert?

PittyJ schrieb:
> Noch mal zur Uhr selber:
> Eigentlich keiner speichert seine Uhrzeit in 6 Variablen (year, month,
> day, hour ...) ab und rechnet damit herum.

Das würde ich so nicht unterschreiben.
Kommt immer drauf an, was man mit der Uhr vor hat.

> Das reduziert den Aufwand, dass man in der Interrupt-Routine dann diese
> vielen If-Vergleiche für unterschiedliche Monate und Schaltjahre hat.

DIe sind für einen AVR harmlos, weil alles auf Bytebene geht.
long-Rechnerei ist allerdings für einen AVR auf nicht gerade 
Zuckerschlecken mit seinen 8 Bit Registern.

Wobei allerdings das hier
1
if(day == 31 && ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && hour == 23 && minute == 59 && second == 59)

schon unnötig komplex ist (denn da wird ja noch wo eine Regel für 30 
Tage sein, eine Regel für den Februar). Da ist man mit einem Array 
besser bedient, in dem die Tage pro Monat stehen und die Weiterschaltung 
anhand der Uhrzeit ergibt sich durch die Schachtelung sowieso von 
alleine. EInzig Schaltjahre erfordern ein bischen Rechnerei.

Aussserdem: genau dieser Teil der Uhrenweiterschaltung STEHT 
vernünftigerweise in der Interrupt Routine, die die Uhr bedient. D.h. 
die Fragestellung stellt sich so gar nicht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren