www.mikrocontroller.net

Forum: Compiler & IDEs Ansi C Frage..


Autor: Chris... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich arbeite gerade die Arikel durch..1a die dinger..:)

aber ich habe eine frage auf bestimmte code zeile:

outp ((1 << RXEN) | (1 << TXEN), UCR);

ich weiss was die zeile macht aber ich versteh die einzelnen zeichen 
net... ich kenne << nur als bit shiftoperand und nicht als zeichen um 
ein bit zu setzen. und dann noch der | das ist für mich eine veroderung 
und macht in meinen augen keinen sinn. wäre super wenn mir einer von 
euch helfen könnte.

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dient zum setzen der Bits RXEN (UART Receiver enable) und TXEN (UART 
Receiver enable) an der ensprechenden Position im UCR (UART Control 
Register).

Autor: Schmittchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich kenne << nur als bit shiftoperand
So wird das hier auch gebraucht.

> und dann noch der | das ist für mich eine veroderung
auch das stimmt so.

(1 << RXEN) schiebt die "1" um genau so viele Positionen nach links, wie 
der Wert in der Konstanten RXEN besagt. RXEN wurde die Zahl 4 
zugewiesen, damit wird aus einer "1" durch 4x schieben das Bitmuster 
00010000.
(1 << TXEN) ergibt 00001000. Die bieden Klammern verODERt wird zu 
00011000 und das wird dem Register UCR zugewiesen.

Schmittchen.

Autor: Chris... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist mir schon klar...ich hatte ja schon erwähnt das ich weiss was 
der befehl macht..nur ich weiss nicht wieso...

Autor: Chris... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hey super danke schmittchen...:D

Autor: Popei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soviel zum thema gut lesebarer code ... ;-)

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist doch ganz einfach zu lesen; sorgar die Klammerung sieht gut aus.
Das ist schön kurz, knapp und präzise.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yo..haste recht NOB...wenn man das verstanden hat ist das echt super...

Autor: Christian Schifferle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich könnte sowas natürlich auch mit 2 Hilfsvariablen und 5 Zeilen Code 
lösen, aber so viel Platz haben wir ja eigentlich gar nicht in unseren 
Controllern oder ;-)

BYTE maske1, maske2;
maske1 = 1 << RXEN;
maske2 = 1 << TXEN;
outp (maske1 | maske2, UCR);

Das Verständnis der Bitschiebebefehle und der Bitoperatoren gehört zum 
Basiswissen bei der C-Programmierung. Kann bei Bedarf alles im Teil 1 
des Tutorials nachgelesen werden.

Gruss
Christian

Autor: Schmittchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber so viel Platz haben wir ja eigentlich gar nicht in unseren Controllern oder 
;-)

Ich sehe zwar den Smiley, trotzdem noch eine Ergänzung:
Die Schreibweise im 1.Posting belegt nur 1 Zeile im Editor, und nur eine 
Zeile im Maschinencode (out UCR, 0x18). Die 0x18 kann der Compiler 
(Präprozessor) schon erzeugen und muß nicht jedesmal zur Laufzeit 
errechnet werden.
In Christians Beispiel werden im Normalfall 4 Zeilen Maschinencode 
daraus. (2x Zuweisung, 1x OR, 1x OUT ; das shift löst der Compiler 
selbst auf).

Theoretische Überlegung:
Eigentlich könnte der Compiler auch Chrisitans Code in eine einzige 
Maschinencodezeile optimieren (out UCR, 0x18). Wenn zuvor sichergestellt 
ist, dass kein Interrupt dazwischen kommen kann, dann kann ich mir keine 
Programmkonstellation/zustand vorstellen, bei dem die Zeilen nicht durch 
out UCR, 0x18 ersetzt werden können!? Ich vermute aber, daß das dem 
Compiler bzw. den Compilerprogrammierern zu weit geht und es nicht so 
gemacht wird.

Schmittchen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Schmittchen

Wenn Du Variablen verwendest, denkt der Compiler, daß Du Dir dabei was 
gedacht hast und optimiert sie nicht so einfach weg.
Sonst hättest Du ja #define genommen:


#define maske1 (1 << RXEN)
#define maske2 (1 << TXEN)
outp (maske1 | maske2, UCR);

So sinds dann wieder nur 2 Zeilen Assembler.

Peter

Autor: Schmittchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn Du Variablen verwendest, denkt der Compiler, daß Du Dir dabei was gedacht 
hast
Ja klar, aber in dem speziellen Falle könnte er sie wegoptimieren, 
ohne die Funktion des Programmes zu verändern. (Ich geb ja zu, daß das 
ein sehr spezieller, konstruierter und weithergeholter Fall ist - 
genauso wie zu fordern, daß der Compiler aus deinem Code nur 1 Zeile 
machen soll.).


Schmittchen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Schmittchen

"genauso wie zu fordern, daß der Compiler aus deinem Code nur 1 Zeile 
machen soll"

Ist doch unmöglich !
Um einen Wert in ein I/O-Register zu schreiben, brauchst Du mindestens 2 
Instruktionen:

ldi r16, 1<<RXEN^1<<TXEN
out UCR, r16


Direkt irgendwas im I/O zu machen geht nur beim 8051 (MOV, INC, DEC, 
DJNZ, ANL, ORL, XRL). Deshalb ist ja Code auf dem 8051 typischer Weise 
kleiner als auf dem AVR.


Peter

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der 8051 braucht ja aber auch 12mal soviele takte pro instruktion! :-)

Autor: Schmittchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Um einen Wert in ein I/O-Register zu schreiben, brauchst Du mindestens 2 
Instruktionen:
Stimmt! Für mich war das eine Instruktion, aber das kann der AVR ja 
leider nicht. Also stimmen meine Angaben oben auch nicht ganz.

Aber manchmal geht der Compiler ja auch zu weit... siehe Beispiele leere 
Warteschleife wegoptimieren (kann der Compiler ja nicht wissen) oder die 
volatile-Geschichte. In beiden Fällen muß man den Compiler explizit 
darauf "hinweisen".

Schmittchen.

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber manchmal geht der Compiler ja auch zu weit... siehe Beispiele leere 
Warteschleife wegoptimieren ...

Nee, das ist schon richtig, das unnützer Code wegoptimiert wird. Wenn 
das nicht gemacht würde, müsste man auch die Kommentare übernehen und 
nicht wegoptimieren!

Wenn Optimierung eingeschaltet ist, sollte eine leere Warteschleife 
immer wegoptimiert werden.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Warteschleife sollte niemals wegoptimiert werden, wenn der 
Compilerbauer mitgedacht hat.

Optimieren heißt doch nur sinnlosen Code zu entfernen aber eine 
Warteschleife ist doch eindeutig als sinnvoll zum Warten zu erkennen.

Wenn ein Compilerbauer also leere Schleifen wegoptimiert, hat er 
entweder keine praktische Programmiererfahrung oder er will den Nutzer 
ärgern.


@Jonas,

stimmt, die meisten 8051 laufen mit 1 MIPS (Quarz = 12MHz), weil das 
oftmals mehr als ausreichend ist. Aber für die 
Geschwindigkeitsfetischisten gibts auch 8051-er mit max 50 MIPS (bzw. 
100 MIPS als Samples), z.B von Cygnal.


Peter

Autor: Christian Schifferle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Aussage kann ich so nicht stehen lassen.
Bedenkt bitte, dass der C-Compiler nicht ausschliesslich zum 
Programmieren von Mikrocontrollern entwickelt wurde und bei "normalen" 
Anwendungen soll schliesslich nicht gewartet, sondern möglichst zügig 
gearbeitet werden.
Insofern ist es aus Sicht des Compilers völlig in Ordnung, für ihn 
sinnlose (weil leere) Loops wegzuoptimieren.

Christian

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Eine Warteschleife sollte niemals wegoptimiert
>werden, wenn der Compilerbauer mitgedacht hat.

Ja, aber eine leere Schleife ist doch keine Warteschleife, ausser man 
sagt das dem Compiler explizit. Ansonsten könnte der Compiler ja nichts 
optimieren!

Beim MSPGCC sieht eine ganz einfache Warteschleife deshalb so aus:

 for(i=0;i<1234;i++) _asm_ __volatile__("; loop");

Das die Schleife ohne volatile wegoptimiert ist doch auch das was man 
haben möchte, denn nach einigen tausend Zeilen Code kann ein Mensch 
wegoptimierbaren Code kaum erkennen, so das der Compiler das übernehmen 
muss.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.