Forum: Compiler & IDEs " % " Zeichen in WinAVR


von Heinz (Gast)


Lesenswert?

Hallo!

Kann bitte jemand so freundlich sein, was dieses "%" Zeichen im
Compiler für eine Funktion hat:

So hab ich folgenden Code vor mir:
(von der time base von Peter Dannegger)

#if XTAL % DEBOUNCE
  OCR1A = XTAL / DEBOUNCE - 1;  // compare DEBOUNCE - 1 times
#endif


Nun habe ich folgenden Fragen:
1.)Wann verwende ich ein

#if Abfrage
Anweisung....
#endif


und wann das normale

if(Abfrage)
{ Anweisungen;
}

?

Und 2.)
Was genau macht die Zeile(also welche Funktion hat das "%" ?

#if XTAL % DEBOUNCE

Ich hätte ja schon selber im manual des WinAV nachgesehen, weiß aber
gar nicht recht, in welchem Kapitel da nachzusehen ist. Sind das
Präprozessor Direktiven?!

Danke für die Hilfe und ne schönen tag noch :-)

von Heinz (Gast)


Lesenswert?

Sorry, was ich vergessen hatte, zu fragen:

Kann mir jemand diese Zeile etwas verinfachter hinschreiben?

TCCR1B = 1<<WGM12^1<<CS10;    // divide by 1

Was bedeutet (allgemein)  1<< Registername^1 ?

Sorry für die möglicherweise dummen Fragen, aber der Code ist für mich
einfach zu "optimiert", also einfach kompliziert zu lesen.

Soll nun keine Kritik an den Autor sein, ich weiß um dessen Kompetenz
Bescheid, nur ist es für mich als Beginner unnötig verkompliziert.

Wahrscheinlich durchschaut man alles viel leichter, wenn man darauf
eben zwei Befelszeilen macht ?! ;-)

DANKE!

von Karl H. (kbuchegg)


Lesenswert?

Zuallererst:
  Geh, nein lauf, in die naechste Buchhandlung und besorge Dir
  Literatur zum Thema: Grundlagen der Programmierung in C.
  Online-Tutorials bzw. Manuals wie sie mit dem Compiler gelifert
  werden sind kein Ersatz für ein ordentliches Einführungsbuch.

  Du wirst ein Buch brauchen!

Zum Thema:
Zeilen die mit '#' beginnen sind Anweisungen an den Preprozessor.
Der ist im Grunde nichts anderes als ein Editor, der den Programm-
Text nochmal verändern kann, bevor ihn der eigentliche Compiler
zu Gesicht bekommt. Der Witz an der Sache ist, dass die Anweisungen
an diesen Editor im Text den er bearbeitet selbst enthalten sind.
Eben jene Zeilen die mit # beginnen.

#if XTAL % DEBOUNCE
  OCR1A = XTAL / DEBOUNCE - 1;  // compare DEBOUNCE - 1 times
#endif

#if  ist also eine Anweisung an den Preprozessor.
Und zwar soll er den Ausdruck XTAL % DEBOUNCE (das werden 2 Makros
irgendwo sein) auswerten, und nur dann wenn da etwas anderes als
0 rauskommt, dann lässt er die nachfolgende Zeile (alles weitere
bis zum #endif) im Text stehen. Ansonsten fliegt dieser Text
aus dem Programmtext raus.

% steht für modulo. Also: Welcher Rest bleibt bei einer Division.
So wie Du es in der Grundschule gelernt hast: Eine Mutter hat
8 Äpfel und 3 Kinder. Wenn jedes Kind gleich viele Äpfel kriegt,
wieviele Äpfel bleiben der Mutter übrig.

von johnny.m (Gast)


Lesenswert?

#if...#endif sind Präprozessor-Direktiven zur bedingten Compilierung.
% ist in C der Modulo-Operator. Ich denke, da soll überprüft werden, ob
XTAL ganzzahlig durch DEBOUNCE teilbar ist. Ist das der Fall, dann ist
XTAL % DEBOUNCE null und das was zwischen #if und #endif steht wird
nicht compiliert. Wenn es nicht null ist (-> XTAL ist kein ganzzahliges
Vielfaches von DEBOUNCE), dann wird die Zeile mit OCR1A compiliert.

Zu dem zweiten Posting: Wenn man das korrekt klammert:

TCCR1B = (1 << WGM12) ^ (1 << CS10);

^ ist der (bitweise) Exklusiv-Oder-Operator. Eigentlich nimmt man für
so was wie oben aber den Oder-Operator | (ich gehe jedenfalls davon
aus, dass mit der Zeile die Bits WGM12 und CS10 in TCCR1B gesetzt
werden sollen). WGM12 ist kein Registername sondern ein Bitname, dem
die Nummer des Bits im entsprechenden Register zugewiesen ist. 1 << BIT
ist eine '1' (00000001), die um 'BIT' nach links geshiftet ist.

Ansonsten: C-Buch besorgen...

Gruß

Johnny

von Karl H. (kbuchegg)


Lesenswert?

> Sorry für die möglicherweise dummen Fragen, aber der Code ist
> für mich einfach zu "optimiert",

Die Frage an sich ist nicht dumm. Nur ist das keineswegs in
irgendeiner Form 'optimiert'. Das ist ganz normales
C-Grundlagenwissen. Daher nochmal: Lauf in die nächste Buchhandlung.

1<<WGM12^1<<CS10

Da stehen 2 Ausdrücke, die mittels ^miteinander verknüpft sind.
^ steht für XOR

( 1 << WGM12 ) ^ ( 1 << CS10 )

<< seinerseits bedeutet: Bit nach links schieben.

1 << WGM12  ist also ein 1-Bit, dass WGM12 mal nach links
geschoben wird. Ich weiss jetzt nicht welcher Zahlenwert
hinter WGM12 steckt. Aber nehmen wir mal an, das wäre eine
5. Selbe Annahme für CS10: da steckt eine 3 dahinter.

Jetzt schalten wir mal um auf binäre Darstellung mit einer
Byte-Breite von 8 bit

1 << WGM12

  also eine 1                             00000001
  die schieben wir 5 mal nach links       00100000

1 << CS10

  eine 1                                  00000001
  3 mal nach links geschoben              00001000

und beide Ausdrücke mit einem XOR verknüpft:

        00100000
 XOR    00001000
       ----------
        00101000

Das ist also das Ergebnis.
   Binaer:   00101000
   Hex:      28
   Dezimal:  40
   umgangssprachlich:  Eine 8 Bit Zahl, bei der das Bit 5 und
                       das Bit 3 gesetzt sind.
                       5, weil WGM12 5 war
                       3, weil CS10 3 war

(Übrigens: ^ ist etwas ungeöhnlich für diesen Vorgang. Normaler-
 weise nimmt man ein ganz normales ODER:  |

    ( 1 << WGM12 ) | ( 1 << CS10 )

von marco (Gast)


Lesenswert?

Ein großes DANKE an johnny m. und Karl Heinz!

Nach den ausführlichen Erklärungen ist das ganze wesentlich klarer
geworden ;-)

Ich werde den Rat befolgen und demnächst die Buchhandlung aufsuchen...

Danke vielmals für die Starthilfe :-)

von Marian (Gast)


Lesenswert?

Hi,

ich würde mich gerne mal einmischen.

<< seinerseits bedeutet: Bit nach links schieben.

Dazu habe ich mal ne Frage! Kann es sein, dass << unterschiedlich
genutzt wird? So wie du es oben beschrieben hast kenne ich es auch( Ein
schift nach links). Aber das hier:( 1 << WGM12 ) bedeutet was anderes
würde ich sagen. Das WGM12 kommt aus dem TimerRegister des µC. Damit
stellt man ein, welchen Mode (Normal,CTC etc-) man nutzen will. Wenn
man nun schreibt: ( 1 << WGM12 ) bedeutet das, dass man das Bit an
dieser Stelle im Register setzt.
Nun zu meiner Frage. Kann mir das jemand eindeutig erklären, warum es
einmal ein shift ist und manchmal auch einfach das setzen eines Bits in
einem Register?

Gruß Marian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Aber das hier:( 1 << WGM12 ) bedeutet was anderes
> würde ich sagen.

Nein, es bedeutet genau dasselbe.  WGM12 ist weiter nichts
als eine kleine Zahl.  Wenn du eine 1 um eine kleine Zahl
nach links schiebst, hast du eine Bitmaske draus gemacht.
Ein Setzen eines Bits wird es erst durch ver-odern, also

TCCR1A |= 1 << WGM12;

was ja ausgeschrieben wäre

TCCR1A = TCCR1A | (1 << WGM12);

von Marian (Gast)


Lesenswert?

Aha, das erklärt natürlich meine Frage.

Mal wieder was dazu gelernt.

Danke und Gruß,

Marian

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.