Hallo, man kann im AVR Studio ja ein Bit mit Einsern in der Form (1 << Position) laden. Gibt es das auch umgekehrt? Bzw gibt es eine bessere möglichkeit ein Port einzulesen und ein bestimmtes, aber per Variable definiertes Bit, auf Null zu setzen? Mit IN temp, PORTX ANDI temp, 0b11101111 OUT ... geht es zwar, aber die Position der Null ist festgelegt und nicht per (Präprozessor-)Variable definierbar. Danke für Hilfe
Neuling schrieb: > IN temp, PORTX > ANDI temp, 0b11101111 > OUT ... > geht es zwar, aber die Position der Null ist festgelegt und nicht per > (Präprozessor-)Variable definierbar. ABer 0b11101111 ist ja nichts anderes als die binäre Umkehrung (aus 0 mach 1, aus 1 mach 0) von 0b00010000. Und das wiederrum ist ja nichts anders als (1<<PD4). D.h. du brauchst die Operation die im Präprozessor einfach diese Umkehrung macht. Das wiederrum macht das Symbol '~'. Aber. Wenn du sowieso in Assembler nur 1 BIt an einem Port setzen bzw. löschen willst, warum benutzt du dann nicht ganz einfach die Spezialbefehle, die Atmel ihren AVR Prozessoren spendiert hat? Siehe AVR-Tutorial (0<<PD4) ist soweit keine sinnvolle Operation. Denn was macht denn das << ? Das ist eine Schiebeoperation. Bei (1<<PD4) wäre das sinnvoll. PD4 ist ja nichts anderes als eine andere Schreibweise für 4. D.h. da steht
1 | 1 << 4 |
und das bedeutet einfach nur, dass eine binäre 1
1 | 0000 0001 |
um 4 BIts nach links geschoben wird
1 | 0000 0001 Original |
2 | 0000 0010 1 mal verschoben |
3 | 0000 0100 2 mal verschoben |
4 | 0000 1000 3 mal verschoben |
5 | 0001 0000 4 mal verschoben |
d.h. das 1 Bit im Original wandert sukzessive nach links. Jetzt mach das mal mit 0 << PD4
1 | 0000 0000 Original |
2 | 0000 0000 1 mal verschoben |
3 | 0000 0000 2 mal verschoben |
4 | 0000 0000 3 mal verschoben |
5 | 0000 0000 4 mal verschoben |
da entsteht genau dasselbe wie im Original. Einen Wert von 0 nach links zu verschieben ist daher eine sonnlose Operation, weil sich nichts ändert. Das Ergebnis ist genauso einfach 0, wie es das Original war.
Genial, Danke! Nach genau so einem Trick habe ich gesucht! Ich gehe davon aus, dass es dann so aussehen muss ANDI temp, ~(1 << STAT0_PWRKEY) STS STAT0, temp richtig? SBI/CBI sind mir bekannt, aber wie man oben schon sieht, sind es nicht nur I/Os, sondern eben auch SRAMs bei denen einzelne Bits gesetzt/gelöscht werden sollen.
1<<0 = 0b00000001 1<<1 = 0b00000010 1<<2 = 0b00000100 1<<3 = 0b00001000 1<<4 = 0b00010000 1<<5 = 0b00100000 1<<6 = 0b01000000 1<<7 = 0b10000000 ~(1<<0) = 0b11111110 ~(1<<1) = 0b11111101 ~(1<<2) = 0b11111011 ~(1<<3) = 0b11110111 ~(1<<4) = 0b11101111 ~(1<<5) = 0b11011111 ~(1<<6) = 0b10111111 ~(1<<7) = 0b01111111
Nachtrag zum Nachtrag von kbuchegg Ich dachte quasi an sowas
1 | 1111 1111 Orig. |
2 | 1111 1110 Null laden |
3 | 1111 1101 ROL |
4 | 1111 1011 ROL |
5 | ... |
Sieben Mal Nix bleibt nix. Du kannst aber jedes beliebige Einser-Muster erzeugen und invertieren. So stellt Dir der Präprozessor auch Dein 00010000 zur Verfügung.
Neuling schrieb: > Nachtrag zum Nachtrag von /kbuchegg/ > > Ich dachte quasi an sowas >
1 | > 1111 1111 Orig. |
2 | > 1111 1110 Null laden |
3 | > 1111 1101 ROL |
4 | > 1111 1011 ROL |
5 | > ... |
6 | > |
Kannst du auch machen - wenn du dem Assembler beibringen könntest einen ROL zur Assemblierzeit zu machen :-) Die << Operation füllt rechts immer mit 0 Bits auf. Daher geht dein Ansatz nicht.
Selber Effekt, aber man überliest nicht die Tilde:
1 | 0xFF^(1<<PD4) |
Wobei ich zugeben muss, ich würde mich auch eher für die Tilde entscheiden...
Karl Heinz schrieb: > Einen Wert von 0 nach links > zu verschieben ist daher eine sonnlose Operation Logisch erfüllt es keinen Zweck, richtig. In bestimmten Fällen wende ich das "Schieben" einer Null wegen der Lesbarkeit des Codes trotzdem an. Zum Beispiel beim Setzen der Prescaler-Bits im Timer: sbr temp, (0<<CS22)|(0<<CS21)|(1<<CS20) ;Vorteiler So sieht man auf den ersten Blick, welche Bits gesetzt sind und welche nicht. Außerdem lassen sich schnell Änderungen vornehmen.
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.