Forum: Mikrocontroller und Digitale Elektronik Einfache Frage zu C: so richtig?


von Hans (Gast)


Lesenswert?

Guten morgen!

Ich habe eine einfache Frage, die mir bestimmt jeder leicht beantworten 
kann.

Ich möchte bei meinem Controller von einem Port bestimmte Ausgänge beim 
Initialisieren definiert auf low haben - die anderen Pins sind mir dabei 
egal.

Kann ich das so schreiben:
1
P5OUT = ( ~0x01 | ~0x04 | ~0x05 );

?

von Nico S. (nico22)


Lesenswert?

Nein. Eher sowas hier:
1
P5OUT &= ~( 0x01 | 0x04 | 0x05 );

Das kann man auch leicht per Zettel und Stift nachvollziehen.

von Volker (Gast)


Lesenswert?

nein, weil durch oder die Nullen überschriben werden.
1
P5OUT =  ~(0x01 | 0x04 | 0x08 );

0x05 passt hier nicht, wenn Du die Bits einselnd ansprechen wikkst.

von Hans (Gast)


Lesenswert?

Volker schrieb:
> 0x05 passt hier nicht

LOL, ja natürlich, Tippfehler, sorry!

Danke!

von Werner B. (werner-b)


Lesenswert?

Oder so
1
P5OUT = ( ~0x01 & ~0x04 & ~0x05 );

P.S.
Unter Brücksichtigung von ...
> die anderen Pins sind mir dabei egal.
... am einfachsten
1
P5OUT = 0;

;-)

von Tip (Gast)


Lesenswert?

Volker schrieb:
> P5OUT =  ~(0x01 | 0x04 | 0x08 );

Besser

P5OUT =  ~((1 << 0) | (1 << 3) | (1 << 4));

P5OUT =  ~( _BV(0) | _BV(3) | _BV(4) );

Dann kann sowas wie mit der "05" auch nicht passieren.

mfg

von Hans (Gast)


Lesenswert?

Tip schrieb:
> (1 << 0)

Also diese Schreibweise ist mir bis heute ein Rätsel, die habe ich nie 
gelernt bei den MSPs mit IAR.

von Bitschieber (Gast)


Lesenswert?

Hallo!

(1<<x) heißt, dass Du die 1 um x Stellen nach links schiebst.

1<<2 bedeutet also, dass die 1 um 2 Stellen nach links geschoben wird:

00000001
00000010
00000100

Somit bekommst Du den Wert 4 was ja zu 2^2 passt. Somit kann man an der 
Schreibweise sofort erkennen, welches Bit manipuliert wird. Im 
Zusammenhang mit den AVR-Bibliotheken wird es dann übersichtlich:

PORTB |= (1<<PB2);    //Setzt das Portbit PB2
PORTB &= ~(1<<PB2);   //Löscht selbiges.

Viele Grüße
Bitschieber

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hans schrieb:
> Also diese Schreibweise ist mir bis heute ein Rätsel
Mir tuts auch weh, da lerne ich lieber die 16 möglichen 
Bit-Kombinationen in einer Hex-Zahl.
Wenn ich 5 höre, sehe ich 0101, und wenn ich A höre, sehe ich 1010...


Bitschieber schrieb:
> PORTB |= (1<<PB2);    //Setzt das Portbit PB2
> PORTB &= ~(1<<PB2);   //Löscht selbiges.
Zusammen mit den Defines hast du ja recht, aber das hier:
> P5OUT =  ~((1 << 0) | (1 << 3) | (1 << 4));
ist Unsinn, weil das niederwertigste Bit 0 ganz links kommt, und zudem 
in einem ganzen Haufen Zahlen und Sonderzeichen versteckt ist.
Ich sehe da schneller was:
> P5OUT = ~0x19;

von Tip (Gast)


Lesenswert?

Lothar Miller schrieb:
> Zusammen mit den Defines hast du ja recht, aber das hier:
>
>> P5OUT =  ~((1 << 0) | (1 << 3) | (1 << 4));
>
> ist Unsinn, weil das niederwertigste Bit 0 ganz links kommt, und zudem
> in einem ganzen Haufen Zahlen und Sonderzeichen versteckt ist.

Der Sinn erschließt sich erst, wenn man die ganzen "magic numbers" durch 
lesbare Bitdefinitionen ersetzt. Von der Abstraktion ist die Verwendung 
des Makros "_BV" natürlich noch besser als direkt "1 <<" zu schreiben.

Und was hast du gegen das Bit 0? Normalerweise sind die Bits von 0 bis 7 
nummeriert und (1 << 0) ist halt eine Darstellung von 2^0.
Die Reihenfolge der Ausdrücke ist alleine durch die Art deiner im Code 
enthaltenen Programmdokumentation bestimmt. Dem Compiler ist das 
schnurz-piep-egal.


mfg

von Tip (Gast)


Lesenswert?

Hans schrieb:
> Tip schrieb:
>> (1 << 0)
> Also diese Schreibweise ist mir bis heute ein Rätsel, die habe ich nie
> gelernt bei den MSPs mit IAR.

Dafür habe ich MSP und IAR nicht gelernt.   ;-)

Die Beschreibung des Links-Shift Operators "<<" findest du in jedem 
C-Buch beschrieben, z.B.
http://de.wikibooks.org/wiki/C-Programmierung:_Ausdr%C3%BCcke_und_Operatoren

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:
> Hans schrieb:
>> Also diese Schreibweise ist mir bis heute ein Rätsel
> Mir tuts auch weh,

Dann solltest du dir mal überlegen, ob du dir als C-Programmierer die 
Dinge nicht so zurecht legen kannst, dass sie für DICH lesbar sind.

Niemand hindert einen das zu tun.
1
#define ERROR_LED    (1 << PB0)
2
3
    PORTB |= ERROR_LED;      // Error LED anschalten


oder
1
#define ERROR_LED    PB0
2
#define ERROR_PORT   PORTB
3
#define TURN_ON( port, bit )    port |= 1 << bit
4
5
6
   TURN_ON( ERROR_PORT, ERROR_LED );


oder (wenn man sinnigerweise alle LED an einem Port gesammelt hat)
1
#define ERROR_LED   PB0
2
#define READY_LED   PB1
3
4
#define LED_PORT    PORTB
5
6
#define LED_ON(led)      LED_PORT &= ~( 1 << led )
7
#define LED_OFF(led)     LED_PORT |= ( 1 << led )
8
9
    if( error ) {
10
      LED_ON( ERROR_LED );
11
      LED_OFF( READY_LED );
12
    }
13
    else {
14
      LED_OFF( ERROR_LED );
15
      LED_ON( READY_LED );
16
    }

Mit ein wenig Makro Magie kann man sich in C leicht die Dinge so zurecht 
legen, dass ein Blinder mit Stock auf 5 Meter Entfernung die Bedeutung 
einer Anweisung erkennen kann UND der Code einfach wartbar ist. Die LED 
musste wegen Hardware-Änderungen den Portpin wechseln: Kein Problem: 1 
#define angepasst und den Rest erledigt der Compiler.
Nur tun muss man es.

Man beachte auch den Zugewinn an automatischer Dokumentation, der durch

      LED_OFF( ERROR_LED );

ensteht, im Vergleich zu

      PORTB &= ~( 1 << 0 );     // Fehler LED ausschalten

Der Kommentar ist direkt in den C-Code selber hineingewandert. Und das 
ist immer ein gutes Zeichen: Jede Änderung, die einen Kommentar 
überflüssig macht, ist eine gute Änderung.

Ein gutes Programm ist nicht nur dadurch gekennzeichnet, dass es 
funktioniert. Ein gutes Programm ist auch so organisiert, dass es leicht 
zu lesen und zu verstehen ist. Dazu gehört auch, dass man den Compiler 
einspannt um sich selbst das Leben leichter zu machen.

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.