mikrocontroller.net

Forum: Compiler & IDEs beginne mit der c programmierung


Autor: markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich fange gerade an für ein Schulprojekt einen AVR zu programmieren. Nun 
ja es klappt eigentlich ganz gut, nur hätte ich da eine Frage zum 
Setzen/Löschen von Bits.
Ich habe da mal was aus dem Tutorial übernommen, kann es aber nicht so 
richtig verstehen.

PORTB=(1<<PB0)|(1<<PB1); dies setzt mir PB0/1 ohne das ganze Register zu 
verändern ?
PORT &= ~(1<<PB2); so kann ich den PB2 löschen, ohne den ganzen Port zu 
manipulieren ?
Was bedeutet das den "ausgeschrieben" dieses | und <<
Kann man das ganze auch in eine Zeile schreiben ?

Vielen Danke für die Hilfe

Markus

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
markus wrote:

> PORTB=(1<<PB0)|(1<<PB1); dies setzt mir PB0/1 ohne das ganze
> Register zu verändern ?

Nein.  Es setzt das Register ausschließlich auf Bits 0 und 1 (also
0x03).  Alle anderen Bits werden gelöscht.

> PORT &= ~(1<<PB2); so kann ich den PB2 löschen, ohne den ganzen Port
> zu manipulieren ?

Ja.

> Was bedeutet das den "ausgeschrieben" dieses | und <<

| ist ein bitweises ODER, das Ergebnis ist also sowas wie die
,,Bitsumme'': alle Bits, die in einem der beiden Operanden gesetzt
waren, werden auch im Ergebnis gesetzt.

& ist ein bitweises UND, im Ergebnis werden nur die Bits gesetzt, die
in beiden Operanden gesetzt sind.  Anders gesagt, es werden alle Bits
gelöscht, die in einem der beiden Operanden gelöscht sind (das erklärt
die Komplementär-Funktion zum ODER).

<< ist der Linkschiebe-Operator.  Wenn man eine 1 um n bits nach links
schiebt, erhält man eine Zahl, in der das n-te Bit (Zählung beginnt
bei 0) gesetzt ist.  Man wandelt eine Bitnummer damit in eine Bitmaske
um.

Denk dran, dass in C die Schreibweise "foo #= bar" eine Kurzform für
"foo = foo # bar" ist, wobei # einer der Operatoren +, -, *, /, %, &,
|, oder ^ sein kann.  (Ich hoffe, ich habe keinen vergessen. ;-)
PORTB &= ~(1 << PB2)
ist also weiter nichts als
PORTB = PORTB & ~(1 << PB2)

  

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"PORTB=(1<<PB0)|(1<<PB1); dies setzt mir PB0/1 ohne das ganze Register 
zu
verändern?"

Nein. PORTB wird komplett neu gesetzt (=). Und zwar mit einer um PB0-mal 
nach links geshifteten 1 (<<) logisch ODER verknüpft mit einer um 
PB1-mal nach links geshifteten 1.

"PORT &= ~(1<<PB2); so kann ich den PB2 löschen, ohne den ganzen Port zu
manipulieren?"

Ja. PORT wird mit dem alten Inhalt von PORT verundet (&=). Und zwar um 
das komplementäre (~) einer um PB2-mal nach links geshifteten 1 (<<).

Z.B. PB2 = 2
1               = 0b00000001
1<<PB2          = 0b00000100
~(1<<PB2)       = 0b11111011
PORT            = 0b11111111
PORT&=~(1<<PB2) = 0b11111011

Autor: markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Herr Wunsch,
oh , dann muss ich also
PORTB|=(1<<PB0)|(1<<PB1);
schreiben wenn ich nur PB0/1 verändern möchte ?

Danke

Markus

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> PORTB=(1<<PB0)|(1<<PB1); dies setzt mir PB0/1 ohne das ganze Register zu
> verändern ?

Was Du meinst ist
PORTB |= (1<<PB0) | (1<<PB1);
Wie Jörg schon gesagt hat, wird in jedem der beiden Klammer-Ausdrücke 
eine binäre "1" (bei 8 Bit "00000001") um "PB0" bzw. "PB1" nach links 
geschoben. "PB0" und "PB1" sind in der Header-Datei definiert als
#define PB0 0
#define PB1 1
Also wird aus "1 << PB0" ein "1 << 0", d.h. in Binärschreibweise 
"00000001". Analog für PB1: "1 << 1" entspricht "00000010", also die "1" 
um eine Stelle nach links geschoben.

Die beiden Ausdrücke kann man jetzt bitweise verODERn:
  00000001
 |00000010
 ---------
  00000011
In dem Ausdruck rechts vom "=" sind jetzt die beiden letzten Bits (lfd. 
Nr. 0 und 1) gesetzt. Wenn man das ganze jetzt mit PORTB verODERt, 
werden die beiden Bits, die in der Maske (also dem (konstanten) Ausdruck 
rechts vom "=") gesetzt sind, in PORTB gesetzt und die anderen Bits in 
PORTB bleiben unabhängig von ihrem Ausgangswert unverändert. Da der 
Ausdruck rechts vom "=" konstant und zur Compilezeit bekannt ist, macht 
der Compiler aus
PORTB |= (1<<PB0) | (1<<PB1);
ein einfaches
PORTB |= 0x03;
wobei "0x03" auch binär als "0b00000011" geschrieben werden kann.

Die Schreibweise mit "<<" dient der besseren Lesbarkeit des Codes. Im 
Prinzip könnte man auch direkt die binäre oder hexadezimale Bitmaske 
hinschreiben, was zumindest bei Portregistern zu keinem großartigen 
Informationsverlust führt. Bei anderen I/O-Registern hingegen ist eine 
reine Zahlenangabe für eine Bitmaske nicht gut lesbar, da man nicht 
sieht, welches Bit da überhaupt gesetzt wird und man erst im Datenblatt 
nachsehen muss, welches Bit an welcher Position im Register steht.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> oh , dann muss ich also
> PORTB|=(1<<PB0)|(1<<PB1);
> schreiben wenn ich nur PB0/1 verändern möchte ?

Ja das stimmt.

Aber gewöhn dir bitte an, ein bischen mit Leerzeichen
deinen Code zu formatieren.

  PORTB |= (1<<PB0) | (1<<PB1);

ist dasselbe, nur durch die Verwendung von Leerezeichen
so umformatiert, dass man auch beim schnellen Hinschauen
sehen kann, was da passiert. Zum einen sticht das |=
besser heraus (und du hast schon gesehen, dass es da
einen wichtigen Unterschied zu = alleine gibt), zum
anderen ist auch das | im rechten Teil der Zuweisung
durchaus etwas was wichtig ist.


Autor: markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok,
ich denke damit sind meine Fragen beantwortet.
Vielen Dank an alle die sich so schnell und gut darum bemüht haben.

Markus

Autor: Armel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich möchte gern wissen, wie ich die Binaire darstellung von Ziffer oder 
Zahlen aus den Bildschirm ausgeben kann. Ich Programmiere momentan in C 
und würde es gern wissen. Ich man könnte es einfach tun ohne die Zahl 
immer durch 2 zu dividieren wie auf dem Papier.
Danke für die Hilfe.
Armel

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
_itoa() könnte das.
Schau dir die Doku zur Funktion mal genau an und
achte auf den letzten Parameter.

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.