www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ausdruck: 1<<PB0


Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir einer diesen ausdruck erklären: 1<<PB0

der taucht immer wieder auf, aber ich versteh nicht was der macht.
danke

Autor: ozo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein Shiftoperator.
http://de.wikipedia.org/wiki/Bitweiser_Operator#Bi...
PB0 ist ein Define aus deinen Headerdateien und steht beispielsweise auf 
3.
Dann steht da (1 << 3)

Autor: Joan P. (joan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
torben schrieb:
> kann mir einer diesen ausdruck erklären: 1<<PB0
>
> der taucht immer wieder auf, aber ich versteh nicht was der macht.
> danke

Da wird ne '1' auf ne Position nach links geschoben (bitweise).
'PB0' gibt an wie weit nach links.. tippen wuerde ich hier, dass in den 
Source-files 'PB0' fuer '0' steht, da es das 0-te Bit von den 8 ist im 
PortB Register (PB7 bis PB0).

Sollte in den Tutorials unter 'Bitmanipulation' auftauchen.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Er berechnet
nimmt also 2 zur PB0-ten Potenz. Mit
.

Dier ergibt eine Binärdarstellung mit nur einer Binärziffer=1, alle 
anderen Ziffern sind folglich 0.

Autor: Sigint 112 (sigint)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Er berechnet
>
> nimmt also 2 zur PB0-ten Potenz. Mit
>
.
>
> Dier ergibt eine Binärdarstellung mit nur einer Binärziffer=1, alle
> anderen Ziffern sind folglich 0.

Knapp vorneben ist auch dabei!
In diesem speziellen Fall ist deine Aussage zwar richtig, aber nur in 
diesem.
Was wird z.B. aus : (3<<2)?!
Der Shift-Operator verschiebt den ersten Operanden um die Stellenzahl, 
nach links oder rechts, die durch den zweiten Operanden angegeben wird.
Richtig dürfte also eher folgendes sein:

mit

Gruß,
  SIGINT

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1<<PB0 = 0b00000001 (0b... = Binärzahl!)
1<<PB1 = 0b00000010
1<<PB2 = 0b00000100
1<<PB3 = 0b00001000
1<<PB4 = 0b00010000
1<<PB5 = 0b00100000
1<<PB6 = 0b01000000
1<<PB7 = 0b10000000

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was is denn 0P1 und 0P2??

Autor: Sigint 112 (sigint)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
torben schrieb:
> was is denn 0P1 und 0P2??

Operand1 und Operand2:

(OP1 << OP2)
oder
(OP1 >> OP2)

P.S.: Ich hab einen Fehler gemacht! Die Gleichung gilt natürlich nur für 
Linksverschiebung!!!

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann könnte man ja genauso:

1<<0 = 0b00000001
1<<1 = 0b00000010
1<<2 = 0b00000100
1<<3 = 0b00001000
.
.
.

schreiben und den hockus pokus mit PB weglassen, oder??

Autor: Sigint 112 (sigint)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@torben: Man kann das weglassen, sollte es aber nicht. Die symbolischen 
Namen dienen dazu den Quelltext lesbar zu machen.

Autor: .... (quadpoint) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@torben

die schreibweise mit dem b gehört nicht zum c-standard von daher ist es 
schon besser wenn man sich die spart, vor allem, wenn man den code 
weitergibt. zum andern ist die bitshift-anweisung mE nach doch einfacher 
zu lesen.

Autor: .... (quadpoint) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>@torben: Man kann das weglassen, sollte es aber nicht. Die symbolischen
>Namen dienen dazu den Quelltext lesbar zu machen.

+ sie machen den code widerverwendbarer/portabler. falls sich mal der 
wert der hinter PB0 steckt ändert, dann brauch man nur an einer stelle 
etwas zu vertauschen.

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn ich das richtig verstanden habe, dann müsste folgender quelltext 
doch ein lauflicht auf meinem stk500 ausgeben, tut er aber nicht, 
wieso??
mfg

#include <avr/io.h>
#include <avr/oldmacros.h>


int main(void)
{
volatile unsigned int i=0, c=0x01, d=0;
  volatile unsigned char temp=0, b=0;


  outp(0xff, DDRB);


  while(1)
  {

    for(d=0;d<8;d++){
        outp(~c, PORTB);
        for(i=0;i<60000;i++);
        c<<1;
          }


    }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
torben schrieb:

Weil das hier
>         c<<1;

wie jeder andere arithmetische Ausdruck ein Ergebnis liefert und nicht c 
direkt verändert. Du tust nichts mit dem Ergebnis. Damit hat c immer 
denselben Wert.

Das ist so wie wenn du erwartest, dass bei

    a + 2;

a seinen Wert ändert, was es natürlich nicht tut. Erst bei

    a = a + 2;

würde auch a tatsächlich einen neuen Wert bekommen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und bitte:

outp(~c, PORTB);

schreib die so, wie man das normalerweise schreibt. Die alten outp sind 
schon lange obsolet

   PORTB = ~c;

Da gibt es keine Misverständnisse und niemand muss wissen, was sich 
hinter outp wirklich versteckt.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Buch zu C und das Tutorial links oben würden auch auch
in diesem Fall helfen, ohne den ehrenamtlichen Vollzeithelfern
hier die Zeit zu stehlen.

Wieso muß man eigentlich jedem Faulenzer jedes Detail einzeln
erklären, nur weil er nichts lesen will?

Mindestens 90% der Beiträge hier drehen sich um Fragen,
die in wenigen grundlegenden Büchern und online durchgekaut sind.

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab z.b. die funktion outp ausm buch "mikorcomputertechnik der atmel 
avr-risc familie" von g. schmitt
aber es steht halt net alles in büchern auserdem is ja niemand gezwungen 
zu antworten. ich finds zwar net, aber will damit niemandem den sonntag 
morgen vermiesen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, aber << steht in JEDEM C-Buch.
Und hier im Tutorial.

Wenn man jedem, der mal lobenswerterweise mal mit Controllern spielen
will, derartige Details einzeln erklären will, kommt hier niemand
mehr zum Arbeiten oder gar zu den interessanten Fragen.

Wenn dir << noch in keinem Buch aufgefallen ist, hast du
auch alle anderen kleinen und großen Dinge von C nicht gesehen
und einfach noch kein C-Buch gelesen.

Soll das hier alles einzeln vorgebetet werden? Jedem Anfänger wieder?
Wozu soll man dann noch Bücher schreiben?

Sinn eines solchen Forums ist doch eher das zu klären, was man
selber nicht herausbekommt, indem Leute sich äußern, die halt
mehr Erfahrung haben auf einem Gebiet.
Aber das zu nutzen, um nicht elementarste Dinge selber zu lesen,
ist m.E. ein Mißbrauch und ziemlich unhöflich.

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<< weis ich auch was heist aber die bedeutung von PB0 steht leider nicht 
im Buch ( in meinen zwei zumindest) geschweige denn wos steht,
aber is ja jetz egal, ich würd nicht noch mehr zeit verschwenden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt weist du es (und merkst es dir auch)
PB0 ist einfach nur ein Platzhalter für eine Zahl.

Im übrigen ist die noch bessere Technik die, auch PB0 nicht direkt zu 
verwenden, sondern sich ein paar anwendungsspezifische #define zu 
machen. zb

#define F_CPU 1000000   // CPU läuft mit 1Mhz

#include <avr/io.h>
#include <util/delay.h>

#define LED_PORT   PORTB
#define LED_DDR    DDRB
#define LED_ROT    PB0
#define LED_GRUEN  PB1
#define LED_BLAU   PB2


int main()
{
  LED_DDR = (1 << LED_ROT) |         // am Led Port die Pins fuer die
            (1 << LED_GRUEN ) |      // Led auf Ausgang schalten
            (1 << LED_BLAU);

  LED_PORT |= (1 << LED_ROT) |
              (1 << LED_GRUEN ) |
              (1 << LED_BLAU );     // Alle LED aus

  while( 1 ) {
    LED_PORT &= ~(1 << LED_ROT);    // rote LED ein
    _delay_ms( 100 );
    LED_PORT |= (1 << LED_ROT);     // und wieder aus
  
    LED_PORT &= ~(1 << LED_GRUEN);
    _delay_ms( 100 );
    LED_PORT |= (1 << LED_GRUEN);

    LED_PORT &= ~(1 << LED_BLAU);
    _delay_ms( 100 );
    LED_PORT |= (1 << LED_BLAU);
  }
}

Siehst du, wie sich hier der Code schon fast selbst kommentiert. In der 
while Schleife ist nicht mehr von PB0 oder PB2 oder dem PORTB die Rede. 
Sondern da steht: Am LED_PORT, welcher auch immer das sein mag, den 
entsprechenden Ausgangspin für die rote Led, welcher auch immer das sein 
mag) auf 1 oder auf 0 schalten.
An welchem Port die LED angeschlossen sind und an welchem Pin dort, ist 
aus der Hauptschleife lesetechnisch komplett rausgehalten worden und in 
ein paar #define am Anfang zusammengefasst.
Das kommt einerseits der Lesbarkeit zu gute, weil ich mir beim 
Porgrammieren nicht merken muss, dass die grüne LED an PB1 angeschlossen 
ist. Auf der anderen Seite kommt es auch der Änderbarkeit zugute, sollte 
eine LED einmal auf einen anderen Pin umziehen müssen. Ich muss nur noch 
an einer Stelle ändern und nicht quer im ganzen Programm PB1 gegen PB5 
austauschen.

Autor: torben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi vielen dank;
is deutlich klarer geworden. schönen sonntag noch.
mfg

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.