Hallo, ich habe da ein Problem, wo ich nicht weiter komme. Folgender Programmauszug: case 0: { sbi (PORTC,1); sbi (PORTC,2); cbi (PORTC,0); PORTD = a |= ( PIND &= 0x80); zaehler = 1; break; } PortD als Ausgänge definiert. Ich will den aktuellen Zustand der Ausgänge einlesen, ein Bit, das ich nicht verändern möchte , herausfiltern ( PORTD.7) und mit den Bits der Variable a logisch ODER verknüpfen. Dabei soll das 7.Bit des Ausgangs seinen Zustand behalten. Nur irgendwie habe ich einen Denkfehler.Somit habe ich mir den Assemblercode angeschaut, und etwas seltsames entdeckt. Assembler Code ( Auschnitt); 27e: 02 97 sbiw r24, 0x02 ; 2 280: c9 f0 breq .+50 ; 0x2b4 282: 08 95 ret 284: a9 9a sbi 0x15, 1 ; 21 286: aa 9a sbi 0x15, 2 ; 21 288: a8 98 cbi 0x15, 0 ; 21 28a: 80 b3 in r24, 0x10 ; 16 28c: 80 78 andi r24, 0x80 ; 128 28e: 80 bb out 0x10, r24 ; 16 290: 80 b3 in r24, 0x10 ; 16 292: 82 2b or r24, r18 294: 82 bb out 0x12, r24 ; 18 296: 81 e0 ldi r24, 0x01 ; 1 298: 0a c0 rjmp .+20 ; 0x2ae In Zeile 28a ließt er den Port ein,in 28c wird mit 0x80 UND verknüpft und in Zeile 28e auf PIND !!! ausgegeben, sowie in Zeile 290 von PIND wieder eingelesen. Doch laut Datenblatt ist PIND nur lesbar !?! Darum müßte er in Zeile 290 den alten PIND Wert wieder einlesen. Ehrlich gesagt, ich verstehe das nicht ganz. Kann mir jemand mal das erklären ? mit freundlichen Grüßen Jogibär
Sowas kommt davon, wenn man 3 Zuweisungen zugleich macht. Schreibs besser hintereinander. Den Compiler interessiert nicht, welche Bedeutung eine IO-Adresse hat. Er führt brav alles aus, was Du hinschreibst, auch wenn es unsinnig ist. Peter
Hallo, danke für deinen Hinweis. Der Fehler lag in < PIND &= 0x80 > Der Compiler verknüpft beide Bytes logisch UND , und speichert dann das Ergebnis in dem ersten Parameter ( in diesem Fall PIND). Deshalb der Schreibzugriff auf PIND. Bin noch nicht solange dabei, ein paar Fehler seien mir gestattet. Jogibär
"Bin noch nicht solange dabei, ein paar Fehler seien mir gestattet." Deshalb ja mein Tip "immer nur eine Zuweisung je Zeile". Mehrfachzuweisungen ergeben selten kürzeren Code, höchstens den Sieg im Unleserlichkeitswettbewerb. Peter
Dazu kommt noch, dass = und |= die gleiche Priorität haben; da kommt je nach Commpiler etwas anderes heraus, aus der Zeile.
Wegen Mehrfachzuweisungen: Auch wenn man es gerne macht, tut es nicht, da dabei schlechterer Code rauskommt. also statt: a=b=c; besser a=c; b=a; schreiben, im ersten Fall liest er den Inhalt von c 2 mal, im zweiten Fall verwendet er das Register wieder. Ist im normalen Code vielleicht egal, aber in Interruptroutinen bringts schon was.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.