Forum: Mikrocontroller und Digitale Elektronik Problem mit Shift-Operation in avr-c Programmierung


von Johannes S. (jo89)


Lesenswert?

Hallo,

bin gerade dabei avr-c zu lernen, habe dabei mit meinem myAVR-Board
schon einiges zum Laufen gebracht.

Jetzt bin ich aber aus dem ATmega8 - Datenblatt auf ein Beispiel
aus der UART-Programmierung gestoßen in dem mir folgende Programmzeile
ein Rätsel ist:


while ( UCSRA & (1<<RXC) )

Hier soll gewartet werden bis im UDR-Register ein Zeichen empfangen 
wurde
also bis das Bit RXC im UCSRA-Register =1 wird

In der Programmzeile oben wird diese Bit (RXC) aber per Shift-Operation
auf 1 gesetzt.

lt. Datenblatt setzt der AVR diese Bit doch automatisch und zum anderen
ist diese Bit schreibgeschützt oder wie ist diese Programmzeile zu 
interpretieren.

UCSRA-Register:

     | RXC  | TXC | UDRE |  FE  | DOR  | PE  | U2X  | MPCM  |
      -------------------------------------------------------
Re/Wr:  R/-   R/W    R/-   R/-     R/-   R/-   R/W    R/W
Init:    0     0      1     0      0      0     0      0


Also funktionieren tut der Code aber wieso??
Wo liegt mein Denkfehler????

Wäre für einen guten Tipp dankbar


Gruß jo

: Verschoben durch User
von Peter II (Gast)


Lesenswert?

Johannes S. schrieb:
> In der Programmzeile oben wird diese Bit (RXC) aber per Shift-Operation
> auf 1 gesetzt.

nein wird es nicht.

Zum setzen braucht man ein "=" was es hier nicht gibt.

von Ingo Less (Gast)


Lesenswert?

Johannes S. schrieb:
> while ( UCSRA & (1<<RXC) )
Ist initial = false, somit wird die while gleich abgebrochen.
So müsste es sein:
1
while (!(UCSRA & (1<<RXC)));

von Johannes S. (jo89)


Lesenswert?

Hallo

ich hab mich da vielleicht etwas missverständlich ausgedrückt
der Kern meiner Frage war/ist der Ausdruck:   (1<<RXC)

zu den ersten beiden Antworten zuerst mal danke aber

---------------------------------------------

"zu Autor: Peter II (Gast)"

setzen eines Bit in einem Register kann auch durch eine
Shift-Operation erfolgen und muß nicht zwingend durch ein
Gleichheitszeichen erfolgen

DDRD = (1<<PD5);    //setzt Bit5 von Register DDRD

--------------------------------------------

"zu Autor: Ingo Less (Gast)"

ob ich schreibe:               oder schreibe:

while(Bit==1){                 while(Bit!=1){
  //mach nix                     UDR=var;
}                              }
UDR=var;

ist das selbe, also kann ich das "!" auch weglassen
je nach dem ob ich in der While-Schleife weitermache
oder danach

---------------------------------------------

mir gehts wie gesagt um die Shift-Operation

(1<<RXC)

hier wird doch Bit "RXC" eindeutig auf 1 gesetzt
obwohl RXC gleich "R/-" ist also nur lesbar und Initialwert =0
nach Programmstart lt. Datenblatt. Mich interessiert die Schreibweise

while ( UCSRA & (1<<RXC) )


das ist für mich Rätselhaft und wie gesagt ich bin Newbie
und ich möchte avr-c von Grund auf lernen nicht nur irgend
welche Code Schnippsel hin und her Kopieren


Gruß jo

von Jim M. (turboj)


Lesenswert?

Johannes S. schrieb:
> mir gehts wie gesagt um die Shift-Operation
>
> (1<<RXC)
>
> hier wird doch Bit "RXC" eindeutig auf 1 gesetzt

Nein, wird es nicht. Schau Dir mal die Definition von RXC an (das ist 
ein Präprozessor Makro), das ist einfach nur eine Zahl von 0 bis 7. Und 
der Compiler - der nach dem Präprozessor läuft - sieht nur noch den Wert 
der Zahl, im Beispiel ist RXC 7:
1
 (1<<7)

von Peter II (Gast)


Lesenswert?

Johannes S. schrieb:
> "zu Autor: Peter II (Gast)"
>
> setzen eines Bit in einem Register kann auch durch eine
> Shift-Operation erfolgen und muß nicht zwingend durch ein
> Gleichheitszeichen erfolgen
>
> DDRD = (1<<PD5);    //setzt Bit5 von Register DDRD

achso und warum ist dann ein Gleichheitszeichen bei dir da?

von Falk B. (falk)


Lesenswert?


von Michael U. (amiga)


Lesenswert?

Hallo,

Johannes S. schrieb:
> mir gehts wie gesagt um die Shift-Operation
>
> (1<<RXC)
>
> hier wird doch Bit "RXC" eindeutig auf 1 gesetzt
> obwohl RXC gleich "R/-" ist also nur lesbar und Initialwert =0
> nach Programmstart lt. Datenblatt. Mich interessiert die Schreibweise

RXC ist eine definition für die Bitnummer von RXC im 8-Bit-Register.
Es ist hier also einfach nur der Wert 7.
(1<<RXC) sagt dem Compiler nur, daß er eine 1 um 7 Stellen nach links 
schieben soll.
Das ist bis hier erstmal eine interne Darstellung eines Wertes, es wird 
also 0b1000000 beim compilieren daraus.

Gemacht wird mit diesem Wert hier garnichts.
Das passiert erst mit UCSRA & (1<<RXC).
Hier wird der Inhalt von UCSRA gelesen und mit diesem Wert UND 
verknüpft.
Das Ergebnis ist also 0b00000000 wenn das Bit in UCSRA 0 war und 
0b100000000 wenn es 1 war.
Bei UCSRA = (1<<RXC) würde der Wert 0b0000000 in UCSRA geschreiben 
werden,
mit UCSRA == (1<<RXC) würde der Inhalt von UCSRA mit 0b10000000 
verglichen werden usw.

Gruß aus Berlin
Michael

von fop (Gast)


Lesenswert?

Michael U. schrieb:
> Bei UCSRA = (1<<RXC) würde der Wert 0b0000000 in UCSRA geschreiben
> werden,

Deine Antwort ist schon sehr gut. Um perfekt zu sein muss es jedoch 
lauten :
"Bei UCSRA = (1<<RXC) würde der Wert 0b10000000 in UCSRA geschreiben
werden,"

von Michael U. (amiga)


Lesenswert?

Hallo,

fop schrieb:
> "Bei UCSRA = (1<<RXC) würde der Wert 0b10000000 in UCSRA geschreiben
> werden,"

Danke für die Korrektur.

Gruß aus Berlin
Michael

von Johannes S. (jo89)


Lesenswert?

Hallo,

und danke nochmals an alle die Antworten haben mir sehr
weitergeholfen, besonders die von "Jim Meba"
Stichwort "Präprozessor Makro"

Gruß jo

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.