Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage AVR While Schleife in C


von Lukas (lukas_f519)


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!

von Olaf D. (Firma: O.D.I.S.) (dreyero)


Lesenswert?

Hi,

der C Standard besagt folgendes:

false == 0

true != 0

Gruß
Olaf

von Lukas (lukas_f519)


Lesenswert?

heißt wohl ich habe irgendwo am Anfang der Skripte den Grundsatz nicht 
richtig verstanden.

Danke dir

von Jim M. (turboj)


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.

von Jim M. (turboj)


Lesenswert?

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

von Wastl (hartundweichware)


Lesenswert?

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

Das wäre auch mein erster Gedanke bzw. Vorschlag gewesen. Aber
Datenblätter lesen und verstehen ist sowas von un-kühl.

von Falk B. (falk)


Lesenswert?

Jim M. schrieb:
> Grundlagenbuch über die Programmiersprache C besorgen und komplett
> lesen.

An den sozialen und didaktischen Fähigkeiten musst du noch ein "wenig" 
arbeiten . . .

von Falk B. (falk)


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
}

von Falk B. (falk)


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.

von Lukas (lukas_f519)


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.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Lukas schrieb:
> Leider, wie so oft in Prüfungssituationen,
> soll es ohne weitere libraries umgesetzt werden. Wenn auch die
> praxisnähe darunter leidet.

Was bitte soll das denn mit dem eigentlichen Thema zu tun haben?

Ach ja, vermeide dann aber unbedingt auch die Nutzung von libc!

von Lukas (lukas_f519)


Lesenswert?

Falk B. schrieb:
>
> Ja
>
> Ja, siehe Bitmanipulation.
>
> Ausgegeben wird da nix, aber berechnet und ausgewertet.
>
> Nein true ist alles ungleich 0.

Mit diesem Eintrag kann man den Thread nun schließen. Du hast mir alle 
meine Fragen beantwortet. Vielen Dank!

von Lukas (lukas_f519)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.