Falle bei lokalen Variablen
|
01.02.2020, 22:40
Beitrag #1
|
|||
|
|||
Falle bei lokalen Variablen
Hallo,
ich habe mehrere Stunden gebraucht, um folgenden Fehler zu finden: In einer Funktion zum Senden eine Zeichens über I2C hatte ich: Code: void sendeDATA0() { Die Bedingung (RegisterWert==0) ist nie erfüllt (was nicht sein kann), die Schleife hängt. Aber so geht es: Code: word RegisterWert; Offensichtlich optimiert der Compiler das wiederholte Lesen aus dem Register weg, weil er erkennt, dass der RegisterWert außerhalb der Schleife nie gebraucht wird. Wenn RegisterWert als globale Variable deklariert ist, dann liest er den Wert auf jeden Fall mehrfach ein, das ergibt sich aus dem Timing. Vielleich hat ja jemend eine Anregung, wie man das (in der IDE) solider programmieren kann. Vielleicht ist ja der nächste Compiler noch schlauer und erkannt auch, dass die globale Variable nie gebraucht wird und optimiert wieder weg. Grüße GuaAck |
|||
01.02.2020, 23:14
Beitrag #2
|
|||
|
|||
RE: Falle bei lokalen Variablen
(01.02.2020 22:40)GuaAck schrieb: Hallo, ...also auf den ersten Blick fällt mir auf das du den Registerwert als word deklariert hast... aber word ist wohl auf dem DUE 32Bit breit bei den ATMegas wohl 16Bit... NUR 16 oder 32 Bit passen in ein I2C Register nicht rein...das dürfte bei allen Prozessoren 8 Bit haben... das werfe ich mal ein ohne nachzusehen. lgbk An alle Neuankömmlinge hier, wenn ihr Code(Sketch) hier posten wollte dann liest euch bitte diese Anleitung durch. 1+1 = 10 ![]() ![]() |
|||
01.02.2020, 23:25
Beitrag #3
|
|||
|
|||
RE: Falle bei lokalen Variablen
Zitat:...also auf den ersten Blick fällt mir auf das du den Registerwert als word deklariert hast... aber word ist wohl auf dem DUE 32Bit breit bei den ATMegas wohl 16Bit... NUR 16 oder 32 Bit passen in ein I2C Register nicht rein...das dürfte bei allen Prozessoren 8 Bit haben... das werfe ich mal ein ohne nachzusehen. Stimmt, RegisterWert hat 32 Bit, weil auch die Register im DUE (Atmel Sam3x) 32 Bit breit sind. Der Sam3X nutzt nur das letze Byte für Daten an oder vom I2C. Aber in anderen Registern (z. B. zum Status) werden auch die höheren Bits genutzt. Gruß GuaAck |
|||
01.02.2020, 23:26
Beitrag #4
|
|||
|
|||
RE: Falle bei lokalen Variablen
(01.02.2020 23:23)GuaAck schrieb: ... Der Sam3X nutzt nur das letze Byte für Daten an oder vom I2C. Aber in anderen Registern (z. B. zum Status) werden auch die höheren Bits genutzt. du meinst da jetzt die Statusregister vom I2C Interfacing ? Weil das andere Register 32 Bit beim DUE haben ist ja normal.. An alle Neuankömmlinge hier, wenn ihr Code(Sketch) hier posten wollte dann liest euch bitte diese Anleitung durch. 1+1 = 10 ![]() ![]() |
|||
01.02.2020, 23:46
Beitrag #5
|
|||
|
|||
RE: Falle bei lokalen Variablen
(01.02.2020 23:26)Bitklopfer schrieb:(01.02.2020 23:23)GuaAck schrieb: ... Der Sam3X nutzt nur das letze Byte für Daten an oder vom I2C. Aber in anderen Registern (z. B. zum Status) werden auch die höheren Bits genutzt. Ja genau, Gruß GuaAck |
|||
02.02.2020, 08:32
Beitrag #6
|
|||
|
|||
RE: Falle bei lokalen Variablen
Hallo,
auf den ersten Blick sehe ich nur, daß volatile fehlt. Der Compiler weiß nichts davon, daß sich der Wert von TWI_SR von außen ändern kann. Er liest das Register also einmal nur beim ersten Durchlauf der Schleife. Also volatile word RegisterWert; Gruß aus Berlin Michael |
|||
02.02.2020, 09:25
Beitrag #7
|
|||
|
|||
![]()
Danke,
"volatile" scheint das gesuchte "Zauberwort" zu sein. Probiere ich heute Abend, bin aber nach der Beschreibung sicher, dass es dann geht. Danke nochmal und viele Grüße GuaAck |
|||
02.02.2020, 18:00
Beitrag #8
|
|||
|
|||
RE: Falle bei lokalen Variablen: Lösung gefunden
So geht es:
Code: volatile word* TWI_SR = (word*)0x4008C020; // HIER volatile!!!! Gruß GuaAck |
|||
|
|
Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste