in der Beschreibung für die Uart gibt es folgende codezeile: ;Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp Was genau heißt das (1<<URSEL)|(3<<UCSZ0)? URSEL und UCSZ0 sind 2 bits aus dem UCSRC Register hätte jetzt gedacht das das sowas heißt wie setze bit an der stelle von URSEL und UCSZ0 auf 1 aber was bedeutet 3<<UCSZ0? Bit auf 3 setzen geht ja schlecht und URSEL ist nicht das erste bit und UCSZ0 nicht das dritte. Bitte klärt einen blöden auf ^^
3<<UCSZ0 Es wird eine 3 UCSZ0-mal nach links verschoben. Man könnte es auch einleuchtender so schreiben: (1<<URSEL)|(1<<UCSZ0) |(1<<UCSZ1)? Hätte den gleichen Zweck.
> hätte jetzt gedacht das das sowas heißt wie setze bit an der stelle > von URSEL So in etwa könnte man das in gesprochenem Deutsch umschreiben. > aber was bedeutet 3<<UCSZ0 Nun. 1 << URSEL ist eine binäre 1 (also: 00000001) URSEL-mal nach links geschoben. Im Endeffekt wird also das Bit mit der Nummer URSEL gesetzt. 3 << UCSZ0 ist eine binäre 3 (also: 00000011) UCSZ0-mal nach links geschoben. Im Endeffekt werden also 2 Bits gleichzeitig gesetzt. Das Bit mit der Nummer UCSZ0 und das gleich links davon stehende.
Danke für die schnellen Antworten Aber Jetzt bin ich eigentlich noch verwirrter als vorher ^^ ;Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp Warum sagt man dann nicht einfach: ldi temp, 0b10000110 out UCSRC, temp Verstehe nicht warum geschoben wird nur weils kürzer ist?
>Warum sagt man dann nicht einfach: >ldi temp, 0b10000110 Weil das für Menschen, nicht wirklich gut lesbar ist. Ausserdem kümmert sich der Preprozessor um die Umsetzung in eine Zahl. Noch kürzer wäre nämlich: ldi temp, 134 Da weiß aber niemand, zu welchen Einstellungen das führt. Die lange Version erhöht die Lesbarkeit wesentlich (könnte man zu Dokumentation hinzuzählen...)
Aha ich dachte nur da ich ja sowiso nicht alle Pinbezeichnungen im kopf habe und ich mir das UCSRC Registerdiagramm vorlege dann kann ich ja genau sagen welches bit ich setzen will 7 6 5 4 3 2 1 0 PIN URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL UCSRC dann also 0b10000110 dagegen finde ich in meinem jugendlichen leichtsinn (1<<URSEL)|(3<<UCSZ0) ehr unverständlicher weil ich die Bits noch nicht richtig kenne und außerdem geht aus der sache ja nicht hervor das UCSZ1 mitgesetzt wird außer mann kennt alles auswendig durch die 3 sehe ich dann das etwas anderes mitgesetzt wird aber nicht was. Habt ihr das alles im kopf und daher ist es für euch verständlicher?
> Verstehe nicht warum geschoben wird nur weils kürzer ist?
Weil du bei
ldi temp, 0b10000110
nach 2 Monaten ins Handbuch schauen und Bits auseinander-
pfriemeln musst, um rauszufinden welche Bits hier gesetzt werden
und was sie bewirken. Ausserdem hast du mit 0b10000110 keinen
wirklich guten Suchbegriff um im Prozessor-PDF nach der Dokumentation
zu den Bits zu suchen.
Dahingehend sagt mir
(1<<URSEL)|(3<<UCSZ0)
zumindest wie die Bits die ich setzen will heissen und ich kann
gezielt im PDF danach suchen. Mal ganz abgesehen davon, dass
ich ohne viel Bit-Pfriemelei auf einen Blick sehen kann, dass
hier das Bit Namens 'URSEL' bzw. 'UCSZ0' + 'UCSZ1' gesetzt
werden.
Bei etwas Übung sagt mir der Bit-Name auch was über die Funktion.
Wenn ich die Funktion nicht auswendig weiss, habe ich zumindest
einen vernünftigen Suchbegriff mit dem ich im PDF suchen kann.
Klingt einleuchtend dann werde ich mir das auch mal angewöhnen. Danke für deine gedult mir das zu erklären. dann mal wieder an die Arbeit. vielen Dank gonzoo
>(3<<UCSZ0)
Finde ich etwas unglücklich. Beim flüchtigen Draufgucken (was einigen
hier im Forum ziemlich häufig passiert), liest man gerne (1<<UCSZ0),
was zu einer falschen USART-Einstellung führt.
Wenn man tippfaul ist, kommt sowas dabei heraus...
> ehr unverständlicher weil ich die Bits noch nicht richtig kenne Aha. Und bei 0b10000110 kennst du die Bits. > außerdem geht aus der sache ja nicht hervor das UCSZ1 mitgesetzt > wird doch, das geht eindeutig daraus hervor. > außer mann kennt alles auswendig Das ist nun wirklich eines der einfachsten Dinge, die man sich merken muss und wenn nicht hat ein normaler Programmierer den Sinn der Sache in unter 10 Sekunden erkannt. Programmierer haben dutzende Algorithmen im Kopf, die sie auch dann runterspulen können (müssen), wenn man sie um 5 Uhr früh weckt. > 3 sehe ich dann das etwas anderes mitgesetzt wird aber nicht was. Das allerdings ist ein Argument. Daher wird man dieses Verfahren (die 3 zu benutzen anstatt zwei einzelner Bit-Setzereien) nur dann benutzen, wenn die beiden nebeneinanderliegenden Bits auch tatsächlich stark miteinander verknüpft sind. Bei 2 Bits die überhaupt nichts miteinander zu tun haben, wäre sowas ansonsten glatter Selbstmord.
hallo leute, zu diesem thema hab ich auch mal eine frage; wenn ich sowas schreibe: (1<<URSEL)|(3<<UCSZ0) bleiben die anderen bits im register leider nicht unangetastet obwohl ich u.u. nicht will, dass die geändert werden (so habe ich es jedenfalls im debugger mehrmals beobachtet). kann mir bitte jemand ein codebeispiel zeigen welches nur die gewünschten bits abändert? so long kalle
In C macht man das so: Setzen von Bits im Byte x: x |= (1<<URSEL)|(3<<UCSZ0); wobei das nichts anderes heisst wie x = x | (1<<URSEL)|(3<<UCSZ0); Löschen geht dann per: x &= ((1<<URSEL)|(3<<UCSZ0)); (Langform analog zu Man liest also das zu ändernde Register aus, verknüpft es logisch mit dem anderen Wert und schreibt es dann wieder zurück. In Assembler gibt es vielleicht andere Methoden/Befehle...
Für I/O-Register gibt's in Assembler nur sbi und cbi, mit denen man ein einzelnes Bit setzen oder löschen kann. Wenn man mehrere Bits ändert, liest man besser den Wert in ein normales Reigster, führt die Verknüpfung aus und schreibt das Ergebnis wieder zurück.
@Rahul: Ich glaub Du hast da ein '~' vergessen: x &= ~((1<<URSEL)|(3<<UCSZ0));
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.