kann mir einer diesen ausdruck erklären: 1<<PB0 der taucht immer wieder auf, aber ich versteh nicht was der macht. danke
Das ist ein Shiftoperator. http://de.wikipedia.org/wiki/Bitweiser_Operator#Bitweise_Verschiebungen PB0 ist ein Define aus deinen Headerdateien und steht beispielsweise auf 3. Dann steht da (1 << 3)
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.
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.
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
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
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!!!
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??
@torben: Man kann das weglassen, sollte es aber nicht. Die symbolischen Namen dienen dazu den Quelltext lesbar zu machen.
@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.
>@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.
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; } } }
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.
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.
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.
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.
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.
<< 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.
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
1 | #define F_CPU 1000000 // CPU läuft mit 1Mhz
|
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | |
6 | #define LED_PORT PORTB
|
7 | #define LED_DDR DDRB
|
8 | #define LED_ROT PB0
|
9 | #define LED_GRUEN PB1
|
10 | #define LED_BLAU PB2
|
11 | |
12 | |
13 | int main() |
14 | {
|
15 | LED_DDR = (1 << LED_ROT) | // am Led Port die Pins fuer die |
16 | (1 << LED_GRUEN ) | // Led auf Ausgang schalten |
17 | (1 << LED_BLAU); |
18 | |
19 | LED_PORT |= (1 << LED_ROT) | |
20 | (1 << LED_GRUEN ) | |
21 | (1 << LED_BLAU ); // Alle LED aus |
22 | |
23 | while( 1 ) { |
24 | LED_PORT &= ~(1 << LED_ROT); // rote LED ein |
25 | _delay_ms( 100 ); |
26 | LED_PORT |= (1 << LED_ROT); // und wieder aus |
27 | |
28 | LED_PORT &= ~(1 << LED_GRUEN); |
29 | _delay_ms( 100 ); |
30 | LED_PORT |= (1 << LED_GRUEN); |
31 | |
32 | LED_PORT &= ~(1 << LED_BLAU); |
33 | _delay_ms( 100 ); |
34 | LED_PORT |= (1 << LED_BLAU); |
35 | }
|
36 | }
|
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.