Gast
#4827136
Ich suche Erklärungen für diese Befehle.
if(ACSR & (1<<ACO)){
PORTC |= (1<<DDC0);
}
else{
PORTC = (0<<DDC0);
Ich habe das ganze gegoogelt aber nix gefunden.
Kann da jemand kurz helfen?
|
Anzeige
|
Unklarheiten bei einem C Programm
Gast
#4827136
Ich suche Erklärungen für diese Befehle.
if(ACSR & (1<<ACO)){
PORTC |= (1<<DDC0);
}
else{
PORTC = (0<<DDC0);
Ich habe das ganze gegoogelt aber nix gefunden.
Kann da jemand kurz helfen?
Gast
#4827143
xXxPu55YD35TrOyEr69xXx schrieb: > Ich suche Erklärungen für diese Befehle. welche Befehle? ich sehe nur Bitoperationen http://home.fhtw-berlin.de/~junghans/cref/CONCEPT/bitwise.html Bist du mit dem Nick auch auf Frauensuche? Kommt bestimmt super an :-)
Gast
#4827149
Die Operationen sind auf dem Link nicht erklärt. Aber Danke
Gast
#4827151
xXxPu55YD35TrOyEr69xXx schrieb: > Die Operationen sind auf dem Link nicht erklärt. Aber Danke welche sind nicht erklärt?
Gast
#4827156
if(ACSR & (1<<ACO)) PORTC |= (1<<DDC0); Ich kenne es sonst nur so hier: DDRB &= ~_BV(PB0)
Gast
#4827163
xXxPu55YD35TrOyEr69xXx schrieb: > if(ACSR & (1<<ACO)) > > PORTC |= (1<<DDC0); und was steht bei dem link? & AND (UND) << Shift Left (Linksschieben |= OR (ODER) etwas kombinieren musst du schon selber
Gast
#4827165
Und wenn ich (1<< PB0) schreibe, dann setze ich PB0 doch auf high?
Gast
#4827169
Warum schreibt man denn PORTC = (0<<DDC0); anstelle PORTC = 0;
Gast
#4827171
xXxPu55YD35TrOyEr69xXx schrieb: > Und wenn ich (1<< PB0) schreibe, dann setze ich PB0 doch auf high? nein - es ist ja überhaupt keine Zuweisung. PB0 ist eine Konstante und kann nie gesetzt werden.
Gast
#4827175
Dr. Ötte schrieb: > Warum schreibt man denn > > PORTC = (0<<DDC0); > > anstelle > > PORTC = 0; Deswegen bin ich ja so irritiert. Und was soll das Linksschieben bewirken? Wäre mehr als dankbar für ne kurze Erklärung.
Gast
#4827187
>Warum schreibt man denn >PORTC = (0<<DDC0); >anstelle >PORTC = 0; Bwiwrkt beides dasselbe, ich weiss auch nicht was das soll. Falls der Programmierer lediglich das Bit vom dem if Statement wieder auf 0 setzen wollte, hat er es falsch gemacht, er setzt alle Bits auf null. Womöglich wollte der Programmierer folgendes:
Dr. Ötte schrieb: > Warum schreibt man denn > > PORTC = (0<<DDC0); > > anstelle > > PORTC = 0; Das schreibt man nur dann so, wenn man nicht verstanden hat, daß es völlig sinnlos ist, Nullen durch die Gegend zu schieben.
Gast
#4827195
Dr. Ötte schrieb: > Warum schreibt man denn > > PORTC = (0<<DDC0); > > anstelle > > PORTC = 0; Wer tut das? Es bewirkt das Gleiche, wenn der Compiler zumindest ein bisschen optimiert, aber das untere ist verständlicher. xXxPu55YD35TrOyEr69xXx schrieb: > Und was soll das Linksschieben bewirken? Wäre mehr als dankbar für ne > kurze Erklärung. Man nimmt eine 1 (0001) und schiebt die um eine gewisse Anzahl an Stellen nach links. Bei zwei Stellen wäre das dann 0100. Damit setzt man das Bit Nummer zwei.
Gast
#4827196
Rufus Τ. F. schrieb: > Das schreibt man nur dann so, wenn man nicht verstanden hat, daß es > völlig sinnlos ist, Nullen durch die Gegend zu schieben. Ohne Optimierung ergibt das ein paar verschleierte NOP ;-)
Gast
#4827200
>> Das schreibt man nur dann so, wenn man nicht verstanden hat, daß es >> völlig sinnlos ist, Nullen durch die Gegend zu schieben. >Ohne Optimierung ergibt das ein paar verschleierte NOP ;-) Nope, das gibt nicht mal ohne optimierung NOPs, Konstanten löst bereits der C-Präprozessor auf.
Gast
#4827202
if(ACSR & (1<<ACO) Schlumpf Dir mal das Datenblatt des verwendeten Mikrokontrollers. Da gibt es bestimmt ein Special Function Register (SFR) mit dem schönen Namen ACSR. Eines der darin enthaltenen Bits nennt sich ACO. Was dieses Bit aussagt, findest Du im Datenblatt. Weiterhin hat Dir ein netter Mensch schon mal was vorbereitet, damit Du schön bequem auf dieses Bit zugreifen kannst. Er hat Dir das SFR unter dessen Namen ACSR zugänglich gemacht. Und er hat ein Define mit der Bitnummer für ACO angelegt. Ist doch toll. Wenn man also jetzt eine 1 so oft nach links schiebt wie die Bitnummer, dann hat man danach eine Zahl in der genau nur das Bit mit dieser Nummer gesetzt ist. Wenn man so eine Zahl, die man auch Maske nennt, mit einem Wert und verknüpft, überlebt nur das eine Bit, alle anderen sind danach 0. Die if-Anweisung hält die Bedingung für wahr, wenn ein Wert ungleich 0 heeraus kommt. Wenn der Wert der Bedingung gleich 0 ist, wird die Anweisung/der Block, der dem if zugeordnet ist nicht ausgeführt. kurz gesagt, wenn Bit ACO in ACSR gesetzt... PORTC = (0<<DDC0); nicht zu erklären, da blöder Fehler PORTC &= ~(1<<DDC0); währe Ihr Preis gewesen.
Gast
#4827206
Mikel schrieb: > Nope, das gibt nicht mal ohne optimierung NOPs, Konstanten löst bereits > der C-Präprozessor auf. sicher? Ich dachte er rechnet nur bei #ifdef sonst NIE.
Gast
#4827212
Und wenn ich (1<< PB0) schreibe, dann setze ich PB0 doch auf high? Wenn du den Pin vorher in den Outputmodus geschaltet hast, ja. BP0 ist als 0 definiert, damit ergibt (1<<BP0)==1=='0b00000001'
Gast
#4827213
Dr. Ötte schrieb: > Und wenn ich (1<< PB0) schreibe, dann setze ich PB0 doch auf high? > > Wenn du den Pin vorher in den Outputmodus geschaltet hast, ja. nein, es wird überhaupt nicht gesetzt dafür braucht man eine Zuweisung (=)
Gast
#4827217
Peter II schrieb: > Mikel schrieb: >> Nope, das gibt nicht mal ohne optimierung NOPs, Konstanten löst bereits >> der C-Präprozessor auf. > > sicher? Ich dachte er rechnet nur bei #ifdef sonst NIE. Wenn du zum Beispiel schreibst: c = 3 + 5; Dann setzt er eine 8 ein. Der Compiler bekommt die 3 und die 5 niemals zu sehen.
Gast
#4827225
Huh schrieb: > Wenn du zum Beispiel schreibst: c = 3 + 5; > Dann setzt er eine 8 ein. Der Compiler bekommt die 3 und die 5 niemals > zu sehen. das schein mein GCC andere Meinung zu sein.
Gast
#4827235
PB0 ist vermutlich als 0 definiert. Das ergibt
auch
genannt. Ein Wert, mit dem nix gemacht wird. Also passiert genau nix. Ziemlich sinnlos, aber vermutlich gültiges C.
Gast
#4827238
Peter II schrieb: > Huh schrieb: >> Wenn du zum Beispiel schreibst: c = 3 + 5; >> Dann setzt er eine 8 ein. Der Compiler bekommt die 3 und die 5 niemals >> zu sehen. > > das schein mein GCC andere Meinung zu sein. Das wage ich auch mal zu bezweifeln. Dafür müsste doch der Präprozessor den Code selber parsen und damit viel mehr 'Intelligenz' haben, als er eigentlich braucht. Es kann sein, dass heutige Präprozessoren das können, aber ist das grundsätzlich oder zumindest normalerweise so?
Gast
#4827241
Dussel schrieb: > Das wage ich auch mal zu bezweifeln. es ist auch nicht so.
Gast
#4827389
xXxPu55YD35TrOyEr69xXx schrieb: > Ich suche Erklärungen für diese Befehle.
Grundsätzlich ist es eine gute Idee lieber mit Namen (Konstanten) statt mit Zahlen zu arbeiten. Das macht Code leserlicher und verdeutlicht die Intension. Deswegen schreibt man lieber auch mal (0<<DDC0) statt einfach nur 0. Denn die 0 alleine kann nicht ausdrücken, dass man explizit das Data Direction Control Bit gemeint hatte. Ist ein bißchen wie der Unterschied zwischen "Ey du da, dritter Sohn von neun!" und "Ey, Klaus!". Kurt schrieb: > Da wird in PORTC das DDC0 (Data Direction Control Bit 0) gesetzt. Es wird nicht gesetzt, es wird abgefragt. Kurt schrieb: > Deswegen schreibt man lieber auch mal (0<<DDC0) statt > einfach nur 0 Dann verrate uns bitte mal, wie du mit dieser sinnfreien 0-Schieberei einzelne Bits eines Registers löschen willst. Alles zum Thema 0-Schieberei hat Rufus oben bereits gesagt. Beitrag "Re: Unklarheiten bei einem C Programm"
Gast
#4827502
Nur zur Klarstellung:
Dem TO ging es wohl nur um die völlig dämliche Zeile
> PORTC = (0<<DDC0);
Die anderen Dinge (Bit abfragen, Bit testen) sind ihm klar.
Die Zeile mit 0<< ist ein bedauerlicher Schreibfehler oder wurde von
einem Bastler durch "probieren" herausgefunden.
Mikel, TO und vermutlich andere haben gepostet, wie man es richtig
macht.
Gast
#4827533
Rufus Τ. F. schrieb: > Kurt schrieb: >> Da wird in PORTC das DDC0 (Data Direction Control Bit 0) gesetzt. > > Es wird nicht gesetzt, es wird abgefragt. Das bezog sich auf die Zeile
Diese Zeile fragt nichts ab, sondern schaltet PC0 auf high. Zumindest wenn das DDRC dafür als Ausgang gesetzt ist. Nach Präprozessor und Optimierung im Compiler wird daraus wohl: [a]sbi PORTC, 0;[/a] Rainer B. schrieb: > Kurt schrieb: >> Deswegen schreibt man lieber auch mal (0<<DDC0) statt >> einfach nur 0 > Dann verrate uns bitte mal, wie du mit dieser sinnfreien 0-Schieberei > einzelne Bits eines Registers löschen willst. > Alles zum Thema 0-Schieberei hat Rufus oben bereits gesagt. Da wird ja nicht wirklich was geschoben. Dass es sinnfrei ist Nullen zu shiften weiß auch der Compiler und optimiert das weg. Aber der Schreiber / Leser des Codes kann so ausdrücken um welches Bit es ihm geht. Und genau diese hier so oft gescholtene, müffelige Zeile zeigt den Grund, warum das vorteilhaft ist:
So kann man schon beim Lesen des Codes erkennen, dass der Autor hier mit 99% Sicherheit einen Fehler gemacht hat: alle 8 Bits statt nur Bit0 zu löschen. Hätte er nur
geschrieben, wäre man davon ausgegangen, dass das Absicht und kein Fehler war. Die Pseudo-Bitshifterei dient einzig dem Zweck die Intension im Code zu formulieren.
Gast
#4827651
Oft wird (0<<XYZ) aus optischen Gründen verwendet (ja, ein Quellcode sollte auch schön und lesbar sein). Beispiel A = (1<<AX5) | (0<<AX4) | (1<<AX3) | (1<<AX2) | (0<<AX1); Natürlich sind die ganzen (0<<AX) vom Code her sinnlos. Das hat aber eine andere Aussage als A = 0b10110; Ein Quellcode ist nicht für den Computer, sondern für den Menschen gedacht. Ich lese einen optisch schönen und sauberen Code lieber, als zusammen gequetschten Wirrwar ohne Kommentare. Ist der Code aber gut genug, braucht man keine Kommentare. Man muss also nicht alles verteufeln, was für den Computer sinnlos ist.
Gast
#4827708
Brummbär schrieb: > Oft wird (0<<XYZ) aus optischen Gründen verwendet Ja, aber in anderen Kontext als im UP. Dort war es entweder falsch oder dämlich
Gast
#4829554
So lasse ich mir das gefallen, da sieht man, welche Bits gesetzt sind, und kann es schnell ändern. Ok, wenn es ein Byte ist, werden 3 weitere Bits kommentarlos auf 0 gesetzt.
Aber bei dem folgenden Ausdruck macht man dem eiligen Leser weiss, hier würde nur Bit DDC0 geändert. In Wirklichkeit wird aber das komplette SFR PORTC auf 0 gesetzt. Ein Quell der Freude, wenn man mal DDC1 benutzt und puff ist es 0 und niemand weiss warum. Da finde ich es klarer = 0 zu schreiben.
Gast
#4829616
Hihi, es ist ja noch schlimmer. In der 'Bitmaske' wird DDC0 (ein Bit aus DDRC) genannt, aber gelöscht wird PORTC - also die Bits PC0..PC7. fop schrieb: > Ein Quell der Freude, wenn man mal DDC1 benutzt und > puff ist es 0 und niemand weiss warum. DDC1 wird von dem Code nicht berührt. Aber wenn Du eigentlich PC1 meinst, dann hast Du voll Recht! Auf jeden Fall ist in der Zeile ein Schaf das knurrt und bellt, egal wie unschuldig es auszusehen versucht. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|