Forum: Mikrocontroller und Digitale Elektronik Assembler Befehl BRLO


von Arthur B. (duri)


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

von Dennis Strehl (Gast)


Lesenswert?

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

von Hannes L. (hannes)


Lesenswert?

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.

...

von Roland Schmidt (Gast)


Lesenswert?

Welches Register benutzt du für Flags?
CPI geht nur mit den Registern 16 bis 31.

von Karl H. (kbuchegg)


Lesenswert?

Sind in Flags noch andere Bits gesetzt?

von Willi (Gast)


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

von johnny.m (Gast)


Lesenswert?

In Assembler-Dateien gibts keine 'Spalten'...

von johnny.m (Gast)


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...

von johnny.m (Gast)


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

von Edward Cardew (Gast)


Lesenswert?

Roland hat recht,

Der einzige Unterschied zwichen beiden Varianten ist:

sbrs geht nur: 0 <= r <= 31

und

cpi geht nur: 16 <= d <= 31


Edward

von Marco S (Gast)


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

von johnny.m (Gast)


Lesenswert?

...Und genau das wollte der TO nach seiner Beschreibung zu urteilen ja
auch...

von Hannes L. (hannes)


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.

...

von johnny.m (Gast)


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...)

von Arthur B. (duri)


Angehängte Dateien:

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.

von johnny.m (Gast)


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.

von Michael U. (Gast)


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

von Arthur B. (duri)


Lesenswert?

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

von Aron (Gast)


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?

von spess53 (Gast)


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

von Aron (Gast)


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...

von Aron (Gast)


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.

von spess53 (Gast)


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

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
Noch kein Account? Hier anmelden.