Forum: Mikrocontroller und Digitale Elektronik nur ne frage zum tutorial


von g0nz00 (Gast)


Lesenswert?

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 ^^

von inoffizieller WM-Rahul (Gast)


Lesenswert?

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.

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von g0nz00 (Gast)


Lesenswert?

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?

von g0nz00 (Gast)


Lesenswert?

kürzer isses ja gar nicht meins ist kürzer

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>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...)

von g0nz00 (Gast)


Lesenswert?

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?

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von g0nz00 (Gast)


Lesenswert?

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

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>(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...

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von Kalle Pohl (Gast)


Lesenswert?

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

von inoffizieller WM-Rahul (Gast)


Lesenswert?

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...

von Rolf Magnus (Gast)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

@Rahul:
Ich glaub Du hast da ein '~' vergessen:

x &= ~((1<<URSEL)|(3<<UCSZ0));

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Stimmt. Die Klammern hatte ich ja schon gesetzt...

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
Noch kein Account? Hier anmelden.