Hallo Ich steh gerade etwas auf dem Schlauch Leute. Fall1: Variable X1 = 01010100 Maske = 00000001 Fall2: Variable X1 = 01010101 Maske = 00000000 Wie muss ich das Vernküpfen, um nur das Bit 0 ( also das rechte) je nach Zustand der Maske zu verändern, während die anderen ihren Zustand halten sollen. Ich finde gerade keine Lösung dafür.
X1 = ((~X1) & Maske) | (X1 & (~Maske)) X1 = (not X1 and Maske) or (X1 and not Maske) X1 = X1 ^ Maske X1 = X1 xor Maske Gruß Hagen
Danke Hagen dein 1. Ansatz funktioniert. hab gedacht sowas wäre einfacher zu realisieren. Mit dem XOR hatte ich auch schon gespielt, aber da kann ich das Bit nur toggeln lassen. Es wird nur im Fall 1 der Wert der Maske angenommen. Fall2 geht damit nicht. Aber ich hab ja schonmal einen Lösungsweg.
die XOR Operation oben ist aber nur das was die Kombination aus and/or/not macht. Sie müsste entsprechend deinen Vorderungen funktionieren ?! Beide Lösungen toggln das Bit wenn in Maske das entsprechende Bit auf 1 gesetzt wurde. Alle Bits die 0 in der Maske sind bleiben unverändert. Somit sind beide Vorschläge identisch. Deine Fragestellung ist nicht ganz eindeutig. Gruß Hagen
Hast schon recht mit der Fragestellung, und das mit dem XOR stimmt auch. So wie ich das beim 2 mal testen sehe. Das Ding, was ich haben will, gibt es wohl garnicht. Ich will nicht toggel, sondern Die Variable soll den Zustand der Maske an einer bestimmten Stelle ( Bit n) übernehemen. Ich werde mir da einfach eine andere Logik überlegen müssen
Naja, geht zumindest nicht in einem Schritt, aber vielleicht so: - alle nicht zu verändernden Bits in Maske auf 1 setzen - X1 mit Maske UND verknüpfen - X1 mit Maske ODER verknüpfen
Ähmmm, nicht ganz, war zu schnell :-= - alle nicht zu verändernden Bits in Maske auf 1 setzen - X1 mit Maske UND verknüpfen - alle nicht zu verändernden Bits in Maske auf 0 setzen - X1 mit Maske ODER verknüpfen
"sondern Die Variable soll den Zustand der Maske an einer bestimmten Stelle ( Bit n) übernehemen." Und woher soll die Funktion wissen, welche Bits übernommen werden sollen ? Du brauchst also immer 2 Variablen, eine Maske, die sagt welche Bits übernommen werden und einen Wert, der dann übernommen wird, z.B.: alt: 00001111 maske: 00110011 wert: 01010101 --------------- neu: 00011101 neu = (alt & ~maske) | (wert & maske); Peter
@Peter&Ingo U R right!! is mir dann auch aufgefallen, das mir da eine Information fehlt (ORT). werds nun mal testen.
schön aber, warum nennst du eine Variable X? nenne sie doch einfach var oder v? oder in dem Fall M für "Maske"! dann bist du wenn du dir das ganze in 3 Wochen nochmals anschaust gleich klug und must nicht noch mal hin und herschauen!!
@ULI X1 steht für eine bestimmte Vorgabe, und trägt numal diese Bezeichnung. Ich will mit dieser Bitmanipulation eine serielle Information in ein Byte einlesen. Aber das läuft irgendwie noch nicht. An PORTD PIND5 liegt jeweils immer das Eingangssignal z.B. 01010101 oder so. Codeschnipsel: int i; int mask; int wert; int delaytime; for(i=0;i<=7;i++) { mask=0x01; mask=mask<<i; wert=bit_is_set(PIND,PIND5); wert=wert<<i; delaytime_x1=((delaytime_x1&(~mask)) | (wert&mask)); } Sollte doch aller Logik nach funktionieren. Aber, delaytime steht dann immer auf null oder eins, aber nimmt nie den Wert des Eingans an. Ich nerve ja ungern mit so Pillepalle Zeug, aber das Ding sollte bis Mittag fertig sein.
Hmmm, zunächst mal sollte delaytime_x1 vor der Schleife initialisert werden (z.B. delaytime_x1 = 0 ). Was mir nicht ganz klar ist, wie Du das Einlesen der ja quasi seriell am PIND5 anliegenden Signalfolge synchronisieren willst. Wenn Du die Schleif so wie angegben durchläufst, ist es gut möglich, das da dann halt PIND5 immer 0 oder 1 hat und damit dann eben nur 00000000 bzw. 11111111 drinsteht. Oder hab ich es irgendwie nicht ganz begriffen? Gruß Ingo
Hallo Ingo hast schon recht, das ist aus dem Code nicht ersichtbar. Ich hab mal den vollständigen Code angehangen. An PORTD,PIND5 liegt ein wechselndes Signal an. Das Sagt mir mein OSZI.
Ahso, nun hab ich's wohl begriffen. Es sollen also 8 Schalter abgefragt werden, die Gemuxt sind. Ich denke mal, da kann man sich das ganze Bit-Verwurschteln sparen, und einfach vor Begin der Schleife X1 auf 0 setzen. In der Schleife zunächst X1 einmal nach links schieben. Dann einfach X1 mit dem Wert verodern. also etwas so: delaytime_x1 = 0; for(i=0;i<=7;i++) { PORTB=i; delaytime_x1 = delaytime_x1<<1; wert=bit_is_set(PIND,PIND5); delaytime_x1 = delaytime_x1 | wert; }
Aber damit kann ich dann den Zustand nur der Schalter nur einmal einlesen. Die Abfrage, läuft aber dauernt in der For(;;). Daher brauche ich X1 auch nicht initialisieren, da der Zustand sich eh ständig ändern kann. Ich will ja evtl. auch mal die Bits zurücksetzen. Das geht aber nicht mir dem verodern. Bei einer einmaligen Abfrage geben ich dir natürlich recht.
Achso, weil Du asynchron auf delaytime_x1 in Interrupt0 zugreifen willst, oder? Na dann mußt Du es doch so machen, wie in Deinem Programm, nur die Veknüpfung scheint nicht ganz zu stimmen. So etwas könnte es gehen: delaytime_x1= delaytime_x1 & (wert|(~mask)); delaytime_x1= delaytime_x1 | (wert&mask);
Naja, oder doch einfach delaytime_x1= ((delaytime_x1&(~mask)) | (wert&mask)); (so wie Peter das oben geschrieben hat :-) Die Frage ist aber, was gibt bit_is_set() wirklich zurück. nur 0x00 und 0x01 ? Wo anders sehe ich erstmal keine Fehlerquelle.
Das sehe ich im Moment genauso. Wenn ich das ganze auf Papier durchspiele funktioniert es ja auch. Ich gehe mal davon aus, das bit_is_set() True oder Fals rausgibt, also 0b0000 0001 oder 0b0000 0000. Was sollte es sonst machen sonst? Gibt es denn alternativen dazu, bit_is_set zu verwenden?
Naja, um sicher zu gehen bzw. zum testen, das man wirklich nur 0x00 oder 0x01 hat, kann man das TRUE oder FALSE ja auch logisch auswerten (was allerdings mehr Rechenleistung verpulvert). wert = bit_is_set(PIND,PIND5)? 1: 0; Aber vielleicht weiß ja jemand, was bit_is_set() wirklich zurückgibt. Ich vermute, das es nur das maskierte Bit zurückliefert, was dann natürlich je nach Bit was anderes für TRUE ergibt.
good man !!! da hatte wir jetzt beide die gleiche Idee if(bit_is_set(PIND,PIND5)) wert=0x01; else wert =0x00; funktioniert: Dann is True oder Falls wohl doch was anderes als 0x00 oder 0x01. vielen Dank Ingo nice WE muss jetzt dringend weiterbasteln, da die Schaltung noch heute fertig werden soll.
Hallo, die Lösung von Ingo funktioniert genau dann am besten (und am einfachsten) auch mit fortlaufendem Einlesen, wenn man in der Schleife for (i.....) eine temporäre Variable verwendet, deren Inhalt am Ende (also als letztes in der Endlos-Hauptschleife) in delaytime_x1 kopiert. Keine Gehirnverrenkung und mann muss sich auch keine Gedanken machen, dass einem der Interrupt mit dem Auslesen von delaytime_x1 in die Suppe spuckt ! MfG, Khani
Ja, das wäre wohl das Beste, in der inneren Schleife eine temporäre Variable verwenden und in der Endlos-Hauptschleife diesen Wert dann an X1 zuweisen. Das vermeidet eine weitere mögliche Fehlerquelle durch den asynchronen Zugriff mit Int0. delaytime_x1= ((delaytime_x1&(~mask)) | (wert&mask)); Denn im ersten Teil des Ausdrucks wird ja zunächst das gerade aktuelle Bit pauschal auf 0 gesetzt (gelöscht). Wenn genau dann der Interrupt auftritt, wird ein möglicherweise fälschlicherweise gelöschtes Bit verwendet, weil die ODER-Verknüpfung mit dem aktuellen Wert ja erst dannach erfolgt. Wär mal interessant, was der Compiler da überhaupt für einen Code erzeugt. In C ist das ja so eine schön einfache Zeile, als ASM-Code dürften es aber doch ein paar Zeilen mehr sein :-) Gruß Ingo
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.