Assembler Befehl BRLO

OP #353628
Lesenswert?

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
Gast #353633
Lesenswert?

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
Gast #353635
Lesenswert?

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...
Gast #353636
Lesenswert?

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
Gast #353638
Lesenswert?

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
#353640
Lesenswert?

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.

...
Gast #353641
Lesenswert?

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...)
OP #353642
Lesenswert?

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.
Angehängte Dateien:
Gast #353643
Lesenswert?

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.
Gast #353644
Lesenswert?

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
Gast #1609595
Lesenswert?

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?
Gast #1609636
Lesenswert?

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
Gast #1609782
Lesenswert?

> 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...
Gast #1609807
Lesenswert?

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.
Gast #1609829
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren