Verständnisfrage AVR While Schleife in C

#7766559
Lesenswert?

Hallo zusammen,

ich bin gerade dabei den Unterricht meiner Technikerschule nachzubereiten.

Nun kam es zu einem Verständnisfrage beim nachvollziehen von Code einer Musterlösung zur Übungsaufgabe.

Natürlich habe ich vorerst das Forum durchsucht usw. aber eine 100% Ja/Nein zu meiner Frage konnt eich daraus nicht ablesen.

Ziel der Übungsaufgabe ist es eine Routine zum beschrieben des EEPROM zu entwickeln.

Musterlösung

1
void saveResetFlag(unsigned char Ursache)
2
{
3
unsigned char oldSREG;
4
oldSREG=SREG; // Sichern wegen IR
5
cli(); // alle IR aus wegen Schreibvorgang
6

7
/* Alle Schreibvorgänge beendet im EEPROM ? */
8
while(EECR & (1<<EEWE)); // Hier mein Verständnisproblem
9

10
/* Adresse im EEPROM festlegen*/ EEARH = 0x00; 
11
EEARL = 0x02;
12

13
// Wert ins Datenregister
14
EEDR = Ursache;
15

16
/* Schreiben vorbereiten */
17
EECR |= (1<<EEMWE);
18

19
/* Schreiben */
20
EECR |= (1<<EEWE);
21
SREG=oldSREG; // SREG zurücksichern
22
}

Nun zur Fragestellung:

Mit der While Schleife while(EECR & (1<<EEWE)); wird geprüft ob das EEPROM zum schreiben bereit ist. Genauer Gesagt ob im EEPROM Control Register (EECR) das Bit 1 (EEWE) EEPROM Write Enable gesetzt ist, also noch ein Schreibvorgang läuft. --> Ist meine Annahme richitg?

Dazu wird mit EECR & (1<<EEWE) das Byte EECR genommen und EECR & (1<<EEWE) alleinig auf das Bit 1 maskiert. --> Ist meine Annahme richitg?

Sofern das Bit1 = 1 ist wird b00000010 also dec 2 ausgegeben Sofern das Bit1 = 0 ist wird b00000000 also dec 0 ausgegeben

Wie reagiert die while Schleife darauf? Bisherig war meine Annahme while(1) entspricht while(true) --> Schleife läuft meine neue Annahme heißt jetzt while(>=1) entspricht while(true) --> Schleife läuft

Was stimmt hier nun?

Ich hoffe mir kann jemand auf die Sprünge helfen. Danke und schönen Tag!

#7766575
Lesenswert?

Grundlagenbuch über die Programmiersprache C besorgen und komplett lesen.

Das 40 Jahre alte Zeuchs ist stellenweise unverständlich wenn man die Hintergünde nicht kennt (hier: was volatile bedeutet für moderne Compiler).

Übrigens würden moderne Optimizer hier sehr wohl eine Tautologie (Endlosschleife) erkennen falls die Variable/Register Definition verkackt wurde (lies ohne volatile).

Falls Du hier nix verstehst: Überlege wann die Bedingung ausgewertet werden muss.

#7766618
Lesenswert?

Lukas schrieb:

Die Musterlösung hat einen kleinen Schöhnheitsfehler. Man minimiert die Zeit der Interruptsperre möglichst. Sprich, man sperrt sie nur für die wenige Befehle, für die sie nötigt ist. Und wenn man keinen 100 Jahre alten avr gcc nutzt, gibt es atomic.h, wo die passenden Macros schon drin stecken, die sich um das SREG kümmern. Eher so.

1
#include "util/atomic.h"
2

3
void saveResetFlag(unsigned char Ursache) {
4

5
    /* Warte auf das Ende aktiver Schreibvorgänge im EEPROM */
6
    /* keine Interruptsperre hier, weil nicht nötig */
7
    while(EECR & (1<<EEWE));  // leere while() Schleife, nur Bedingung prüfen
8
    EEARL = 0x02;       // Adresse im EEPROM festlegen
9
    EEDR  = Ursache;    // Wert ins Datenregister
10

11
    /* diese beiden Befehle dürfen nicht durch Interrupts unterbrochen werden */
12
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
13
        EECR |= (1<<EEMWE);     // Schreiben vorbereiten 
14
        EECR |= (1<<EEWE);      // Schreiben
15
    }
16
}
#7766621
Lesenswert?

Lukas schrieb:

Nun zur Fragestellung:

Mit der While Schleife while(EECR & (1<<EEWE)); wird geprüft ob das EEPROM zum schreiben bereit ist. Genauer Gesagt ob im EEPROM Control Register (EECR) das Bit 1 (EEWE) EEPROM Write Enable gesetzt ist, also noch ein Schreibvorgang läuft. --> Ist meine Annahme richitg?

Ja

Dazu wird mit EECR & (1<<EEWE) das Byte EECR genommen und EECR & (1<<EEWE) alleinig auf das Bit 1 maskiert. --> Ist meine Annahme richitg?

Ja, siehe Bitmanipulation.

Sofern das Bit1 = 1 ist wird b00000010 also dec 2 ausgegeben Sofern das Bit1 = 0 ist wird b00000000 also dec 0 ausgegeben

Ausgegeben wird da nix, aber berechnet und ausgewertet.

Wie reagiert die while Schleife darauf? Bisherig war meine Annahme while(1) entspricht while(true) --> Schleife läuft

Ist ja auch so.

meine neue Annahme heißt jetzt while(>=1) entspricht while(true) --> Schleife läuft

Was stimmt hier nun?

Nein true ist alles ungleich 0.

#7766665
Lesenswert?

Falk B. schrieb:

Lukas schrieb:

Die Musterlösung hat einen kleinen Schöhnheitsfehler. Man minimiert die Zeit der Interruptsperre möglichst. Sprich, man sperrt sie nur für die wenige Befehle, für die sie nötigt ist. Und wenn man keinen 100 Jahre alten avr gcc nutzt, gibt es atomic.h, wo die passenden Macros schon drin stecken, die sich um das SREG kümmern.

Okay, danke für den Hinweis. Leider, wie so oft in Prüfungssituationen, soll es ohne weitere libraries umgesetzt werden. Wenn auch die praxisnähe darunter leidet.

#7766672
Lesenswert?

Jim M. schrieb:

Nachtrag: Schau auch im Datenblatt der MCU nach wann das Bit "1" und wann es "0" sein muss.

Danke dir für deine konstruktiven Vorschläge. Das Datenblatt zum Controller habe ich natürlich da und auch gelesen/durchforstet. Wie du sehst ging es mir um die Bestätigung meiner Annahme. Selbst wenn ich die Antwort zu meiner Frage irgendwo im Grundlagenbuch oder Datenblat gelesen habe, fehlte mir in diesme konkreten Fall die Bestätigung meiner Annahme.

Den C Grundkurs in maximaler Länge werde ich mir übrigens schenken. Leider handelt es sich hier um ein Fach von vielen die für den Abschluss nötig sind. Die Zeit zwischen den Prüfungsblöcken reicht leider nicht aus um eine Programmiersprache so tief zu erlenen. Vorallem wenn das Ziel lediglich das bestehen einer Prüfung ist. Wäre es das Ziel C in gänze zu erlenen müsste man viele Weiterbildungsmöglichkeiten inhaltlich grundlegend verändern.

Bisher kannte ich es aus Foren, vorallem hier. Das einem geholfen wird.

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