Hallo liebe Netzbewohner Ich habe einen komischen Effekt mit meinem Roboter. Um 2 Motoren zu synchronisiern zähle ich die Umrehungen. Nach 50 Umdrehungen stoppe ich den Motor A und setzen ein Bit 7 in einem Register. Dasselbe mach ich mit Motor B und Bit 6. Wenn Bit 6 & 7 gesetzt sind, starte ich beide Motoren wieder. Der Restart sollte so aussehen: ************************************************************* cpi Flags,0b11000000 brlo Motor_asynchron ;Ist Reg Flags < 192 dann jump ldi temp,120 out OCR1AL,temp ;LowByte Motor A PWM-Wert out OCR1BL,temp ;LowByte Motor B PWM-Wert cbr Flags,0b11000000 ;Lösche Motorüberwachungbits Motor_asynchron: *************************************************************** Das funktioniert aber nicht ! Darum hab ich Folgendes gemacht: *************************************************************** sbrs Flags,6 ;kontolliere Bit 6 skip if 1 rjmp Motor_asynchron sbrs Flags,7 ;kontolliere Bit 6 skip if 1 rjmp Motor_asynchron ldi temp,120 out OCR1AL,temp ;LowByte Motor A PWM-Wert out OCR1BL,temp ;LowByte Motor B PWM-Wert cbr Flags,0b11000000 ;Lösche Motorüberwachungbits Motor_asynchron: **************************************************************** Und so gehts einwandfrei. NUR: Ich kapier das nicht. Warum kann ich die beiden Bits nicht mit dem BRLO befehl filtern ? Hat jemand eine Erklärung für diesen Effekt ? Gruss Duri
Also so auf Anhieb fällt mir dafür keine Erklärung ein. Hast du's mal mit Test auf Un-Gleichheit versucht, also: cpi Flags,0b11000000 brne Motor_asynchron MfG
Falls es in "flags" noch andere Flags gibt (ist bei mir meist so), dann solltest du die benutzten Flags maskieren und dann auf Gleichheit testen. ...
Welches Register benutzt du für Flags? CPI geht nur mit den Registern 16 bis 31.
Mal ganz blöd gefragt weil ich auch keine andere Erklärung habe: DAS "brlo" steht aber nicht in der ersten Spalte der Zeile wie in deinem Beispiel im ersten Post ? Die Assemblerbefehle dürfen m.E. erst ab der zweiten Spalte stehen. Mfg Willi
Immer wieder das selbe: Was funktioniert an der ersten Version nicht? Gibt es eine Fehlermeldung beim Assemblieren oder funktioniert das Programm im µC nicht?? Verstehe echt nicht, warum manche Leute solche Informationen nie auf Anhieb rausrücken...
Also mir würde jetzt auch nur die Möglichkeit einfallen, dass Flags nicht im 'richtigen' Register steht. Das müsste dann aber bereits beim Assemblieren ne Fehlermeldung geben... Eigentlich sieht es sonst ganz vernünftig aus
Roland hat recht, Der einzige Unterschied zwichen beiden Varianten ist: sbrs geht nur: 0 <= r <= 31 und cpi geht nur: 16 <= d <= 31 Edward
Der Befehl cpi flags, 0b11000000 setzt das Statusregister gemäß dem Ergebnis der Operation (flags-0b11000000). Ist flags==0b11000000, so ist das Ergebnis 0 und das Carrybit wird nicht gesetzt. Der Befehl brlo Motor_asynchron wertet das Carrybit aus. Ist es gesetzt, wird nach Motor_asynchron verzweigt. Gruß Marco
...Und genau das wollte der TO nach seiner Beschreibung zu urteilen ja auch...
Aber warum zum Teufel mit dem Carry-Flag (Übertragsflag)? Temp. Hilfsregister zum Maskieten nehmen, falls "flags" weitere Booleans enthält. mov temp,flags ;temporäre Kopie andi flags,0b11000000 ;nur die relevanten Bits, dabei Zero-Flag ;beeinflussen breq KeinFlagGesetzt ;Verzweigung, falls kein Flag gesetzt ist cpi temp,0b11000000 ;Test auf beide Flags (-> Zero) breq BeideFlagsGesetzt ;Verzweigung, falls beide Flags gesetzt sind ;oder brne EinFlagGesetzt ;Verzweigung, falls nur ein Flag gesetzt ist ;(egal welches der beiden) Falls "flags" die anderen Bits nicht nutzt, kann die Maskierung auch in "flags" erfolgen. ...
Naja, das was der TO geschrieben hat, funktioniert aber für seine Zwecke. Möglicherweise ist es von der Logik her ein wenig weit hergeholt, aber der Code ist kurz (vielleicht hat er ja Probleme mit Speicher oder Ausführungszeit;-) und er braucht kein zusätzliches Register (OK, kann man in temp machen...)
Danke für das Interesse. Ich möchte ein paar Fragen beantworten: 1. Keine Fehlermeldung im Compiler. 2. Der Code mit dem brlo Befehl funktioniert im ATmega8535 nicht. 3. Das Register ist > r16 (R21). 4. Im Register Flags werden noch ander Bits benutzt. Ich sehe aber das es keinen Sprung gibt wenn Bit6 ODER Bit7 gesetzt ist. Ich möchte aber dass es keinen Sprung gibt wenn Bit6 UND Bit7 gesetzt ist. (if flags<192 then jump) Das beste ist aber, dass der Block im debuger so läuft wie ich mir das vorstelle. Auf jeden Fall haben mir die Antworten bestätigt, dass ich prinzipiell keinen Denkfehler gemacht haben. Trotzdem seltsam. Wer Lust hat kann sich den Code im Anhang mal ankucken.
Wie von Hannes schon gesagt: Logisch wäre eine Überprüfung mit breq. Versuch das mal. Sollte mich wundern wenns nicht funktioniert. Deine Methode mit brlo sollte zwar auch funktionieren, aber wenn mans logisch einwandfrei machen will, dann mit Maskierung und breq.
Hallo, eben, seine Methode sollte gehen, nur scheint sie das eben nicht zu machen. Natürlich kann man sowas auf viele Arten machen... Wenn er Bit6 und Bit7 benutzt und den Zustand "wenn nicht beide gesetzt" als einzige Bedingung braucht, gibt es keinerlei Grund, es nicht so wie er zu machen. Wenn nur Bit6 oder Bit7 gesetzt ist, ist der Registerwert < 192, egal, wie die restlichen Bits stehen. Es können nur maximal 191 werden. Ich wüsste also wirklich nicht, warum was anderes "logischer" sein sollte. Ich hatte auch schonmal eine seltsamen Effekt genau mit BRLO auf einem Mega16. Ich bin der Sache leider damals auch nicht weiter nachgegangen, sonder habe umgebaut... Was bleibt, ist aber immernoch die Frage: warum geht BRLO nicht, wie man es erwartet? Gruß aus Berlin Michael
Gutes Schlusswort von Michael U. "warum geht BRLO nicht, wie man es erwartet?" Man weiss es nicht. Also ich werde keine Zeit mehr verschwenden und Lösung 2 benutzen. Besten Dank für das Interesse und Gruss an Berlin Duri
Moin, auch wenn ich den Beitrag ganz unten aus der Versenkung auskrame, ich hatte ähnliche Probleme beim Umstieg vom Mega8 auf den Mega32. Auch andere Sprungbefehle gingen teilwiese nicht. Irgendwie überschreibt der Mega32 beim Vergleich nicht alle relevanten Flags. Beispiel: cpi temp1,3 brlo irgendwohin --> ging nur manchmal, wohl je nachdem wie die Flags gesetzt waren. clc cpi temp1,3 brlo irgendwohin -->funktioniert problemlos. Auch mit Sprungbefehlen die mit dem N und Zflag arbeiten hatte ich teilweise starke Probleme, so das kein Ausweichen möglich war. Evt ist die Mega16er Baureihe etwas allergisch auf cp und cpi´s?
Hi >Irgendwie überschreibt der Mega32 beim Vergleich nicht alle relevanten >Flags. Blödsinn. Die Befehle sind für alle AVRs identisch. BRLO ist eine andere Schreibweise für BRCS. >cpi temp1,3 >brlo irgendwohin Der Sprung wird ausgeführt wenn temp1 0,1 oder 2 ist. Hast du etwas anderes erwartet? MfG Spess
> Der Sprung wird ausgeführt wenn temp1 0,1 oder 2 ist. > Hast du etwas anderes erwartet? Ohne vorher den C zu löschen eben nicht. Selbst wenn ich das Register vor dem Vergleich direkt mit einem Wert bestücke springt er nach dem Zufallsprinzip, erst mit vorherigen löschen des Cflags funktioniert das. Am Mega8 gabs da keine Probleme mit fast identischen Code. Mir ging es darum das ich dieses Problem hatte und offensichtlich auch andere damit ein Problem hatten bzw haben (siehe oben), theoretisch gehts, da stimm ich Dir zu aber praktisch hackt mein Mega32 dabei. Vielleicht kannst Du mir verraten warum mein Programm funktioniert wenn ich vor dem Vergleich Carry lösche? Sollte ja beim cpi überschrieben werden, macht er aber nicht immer. Ach ja, SREG tu ich im UP des Int sichern und am Ende laden, das kanns auch fast nicht sein...
So, es scheint als hätte jemand beim umschreiben das Register, welches nur fürs SREG sichern war doch noch für was anderes benutzt. Mal probieren ob das jetzt vielleicht besser klappt, jetzt macht so einiges Sinn.
Hi >Selbst wenn ich das Register vor dem Vergleich direkt mit einem Wert >bestücke springt er nach dem Zufallsprinzip, erst mit vorherigen löschen... Woher weißt du das? Zumindest im Simulator geht das problemlos. Hänge am besten mal den Programm an. MfG Spess
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.