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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.