Hallo uC-Gemeinde,
ich habe ein Problem mit dem Inkrementieren eines oder mehrerer Bits in
einem Bitfeld.
Folgender Code inkrementiert alle Member des Bitfelds:
1
staticvolatilestruct{
2
unsigneda:3;
3
unsignedb:3;
4
unsignedc:2;
5
}status;
6
7
status.a++;
status.a += 1; funktioniert auch nicht.
Die direkte Zuweisung eines Wertes hingegen funktioniert.
Kann mir jemand sagen warum?
Vielen Dank im Voraus.
Gruß,
Hans.
Hallo A.K.,
der Compiler ist der gcc. Ich glaube nicht, dass der Fehler hier liegt.
Hier dein kompilerbares Beispiel.
Hab leider keine echte Hardware da, aber kann es sein, dass der
Simulator des AVR-Studios einen Bug hat?
Der Debugger im Studio wird vermutlich mit Bitfeldern einfach nichts
anzufangen wissen. Deshalb wird er dir für alle drei (a, b und c) den
Wert des kompletten Bytes als Inhalt präsentieren.
A. K. schrieb:
> Woran erkennst du in diesem Beispiel, dass das ganze Byte inkrementiert> wird? Es wird so oder so 1 rauskommen.
Ich schau mir die einzelnen Member im AVR-Simulator an.
"Es wird so oder so 1 rauskommen" -> Versteh grad nicht, was genau du
mit dieser Aussage meinst...
@Stefan:
Mit der Aussage könnte ich schon mehr anfangen. ;-)
Hans schrieb:
> "Es wird so oder so 1 rauskommen" -> Versteh grad nicht, was genau du> mit dieser Aussage meinst...
Vorher:
a = 0, b = 0, c = 0. Byte = 0.
Nachher:
a = 1, b = 0, c = 0. Byte = 1.
A. K. schrieb:
> Hans schrieb:>>> "Es wird so oder so 1 rauskommen" -> Versteh grad nicht, was genau du>> mit dieser Aussage meinst...>> Vorher:> a = 0, b = 0, c = 0. Byte = 0.> Nachher:> a = 1, b = 0, c = 0. Byte = 1.
Ok, das wäre das, was ich erwartet hätte. Der AVR-Simulator sagt aber
folgendes:
Vorher:
a = 0, b = 0, c = 0.
Nachher:
a = 1, b = 1, c = 1.
Ja, weil:
Stefan Ernst schrieb:
> Der Debugger im Studio wird vermutlich mit Bitfeldern einfach nichts> anzufangen wissen. Deshalb wird er dir für alle drei (a, b und c) den> Wert des kompletten Bytes als Inhalt präsentieren.
Hallo,
ich nochmal.
Ich habs es gerade nochmal auf der echten Hardware ausprobiert.
Da ist es genauso.
Der Fehler muss also doch woanders liegen...
Hat jemand ne Idee?
Gruß,
Hans
Hä? Was ist da genau so? Natürlich werden die 3 Bitfeldvariablen in
einem Byte gespeichert, wieso sollte das auch anders sein?
Es funktioniert alles wie du willst.
@Hans: Vermutlich hast du den gleichen defekten Debugger diesmal auf die
echte Hardware gehetzt. Naturgemäss mit dem gleichen Ergebnis. Nicht die
Simulator-Engine ist das Problem, sondern der entweder darauf oder auf
der echten Hardware aufsitzende Debugger.
So, jetzt hab glaube ich verstanden zu haben, was da vor sich geht.
1
staticvolatilestruct{
2
unsigneda:3;
3
unsignedb:3;
4
unsignedc:2;
5
}status;
Für das Struct werden im Speicher 8Bit reserviert. (Erkennbar an den
daraufolgenden Speicheradressen)
Komischerweise, liest das AVR-Studio 16 Bit ein.
Ich habe aber 2 dieser Structs nebeneinander im Speicher, daher liest er
wenn Struct1 und Struct2 ist 257 als Wert für Struct1 ein.
Der Fehler ist nicht nur im Simulator, sondern auf dem Atmel läuft der
Zugriff auch falsch ab, weil Abfragen auf Struct1 == 1 dann falsch
ausgewertet werden.
Mit
1
staticvolatilestruct{
2
unsignedchara:3;
3
unsignedcharb:3;
4
unsignedcharc:2;
5
}status;
funktioniert das Ganze.
Was sagt ihr dazu?
Gruß,
Hans.
Bis zum Beweis des Gegenteils glaube ich dem Compiler und misstraue der
Variablenanzeige des Debuggers. Probier mal mit der ursprünglichen
Version
volatile unsigned temp;
...
status.a++;
temp = status.b;
und schau danach rein, was in temp steht. Vermutlich der korrekte Wert.
M.a.W: Du kämpfst grad gegen Gepenster. Weder Compiler noch Simulator
noch Hardware machen etwas falsch, sondern die Anzeige der Daten ist
falsch. Hast du wohlmöglich den Optimizer eingeschaltet?