Hi Leute,
ich komme bei meinem Projekt so richtig voran.
Nun stoppe ich an einer kleinen Sache aber ich komme nicht dahinter wie
man es geschickt umgehen kann. :-(
Ich habe nun wohl eine Grenze überschritten...
In der BRNE Zeile bleibt der Compiler hängen und meint...
": error : Relative branch out of reach"
cpi r16,'A'
brne CMD_END
...
nen paar Zeilen Code
...
CMD_END:
ret
Nun was er meint weiß ich... ;-I
CMD_END ist mehr als -64 bzw. +63 Worte entfernt...
Kann mir einer mal nen Tip geben wie ich denoch dahin springen kann?
Gruß AVRli...
mit nem zusätzlichen jmp befehl.nimm nen cmd mit bedingung genau
umgekehrt zu der die du haben willst, der den nächsten befehl
überspring und dann kannst du als nächsten befehl den richtigen jmp
machen. ein bissl konfus, ich weiss :)
Hi,
baue eine Hilfskonstruktion mit einem rjmp welcher deutlich weiter als
63 Worte reicht :)
Also:
cpi r16,'A'
breq GO_ON
rjmp CMD_END
GO_OM:
...
nen paar Zeilen Code
...
CMD_END:
ret
Danke für die schnelle Antwort! ;-)
Ist aber sehr aufwendig wenn man mehrere Zeichen vergleichen muss. ;-(
Also ich wollte wieder raushüpfen wenn eine bestimmte Zeichenfolge
nicht da ist.
Beispiel "ABC"
Das habe ich nun immer so gemacht...
ld r16,X+
cpi r16,'A'
brne CMD_END
ld r16,X+
cpi r16,'B'
brne CMD_END
ld r16,X+
cpi r16,'C'
brne CMD_END
...
nen paar Zeilen Code
...
CMD_END:
ret
Das währen dann 3 Hilfsfunktionen... was für ein "durcheinander"...
;-)
Ich probiere es trotzdem mal...
Gruß AVRli...
Mmmh, das ist als würdes du vielfache if-thens schachteln, also sowieso
nicht gut :->
Kannst du nicht deinen String irgendwo als Konstante ablegen und dann
per Y indiziert in einer Schleife abarbeiten?
Grüße
Hi Thomas,
da hab ich noch keine Ahnung von.
Da fängt es dann wieder an spannend zu werden. :-)
Also ich lese meine Kommandos via RS232 in den SRAM
auf denn kann ich auch zugreifen...
Konstante würde ich so machen...
CMD_ABC:
.db "ABC"
Und nun in einer Schleife SRAM mit CMD_ABC vergleichen...
gibt es einen Unterschied dann raus ansonsten weiter...
Ansatz ok?
Gruß AVRli...
dann machs erstmal so:
ld r16,X+
cpi r16,'A'
brne CMD_END1
ld r16,X+
cpi r16,'B'
brne CMD_END1
ld r16,X+
cpi r16,'C'
brne CMD_END1
rjmp weiter
cmd_end1: rjmp cmd_end
weiter:
...
nen paar Zeilen Code
...
CMD_END:
ret
Nicht die eleganteste Art, aber erstmal verständlich und
funktionierend, kannst also erstmal weiterarbeiten. Die Feinheiten
kommen später :-)
Das einzelne Vergleichen jedes einzelnen Zeichens ist doch sehr Mühsam.
Voallem, wenn es häfiger Vorkommt.
Habe mal schnel ohne AVR-Studio ein kleines Beispiel gemacht, wie man
es "routinieren" könnte.
Der Pointer auf den Eingabetext ist in X (XL,XH).
ldi zl,low(Text1*2)
ldi zh,high(Text1*2)
rcall TextVergleich
brne VergleichText2
...
nen paar Zeilen Code
...
ldi zl,low(Text2*2)
ldi zh,high(Text2*2)
rcall TextVergleich
brne VergleichText3
TextVergleich:
clr r16 ;Ausgangsflag auf 0 setzen
TV1:
lpm r17,z ;n-tes Zeichen nach r17 aus dem Flash lesen
addw zl,1 ;Z-Pointer auf das nächste Zeichen verschieben
tst r17 ;Schon am Ende des Vergleichtextes angekommen?
breq TVExit ;Dann Vergleich positiv und raus
ld r18,x+ ;n-tes Zeichen des Eingabetextes nach r18
cp r17,r18 ;Sind die Zeichen gleich?
breq TV1 ;Wenn ja, dann nächstes Zeichen prüfen
com r16 ;Ansonsten Vergleich auf negativ setzen (0
complement = FF in r16)
TVExit:
tst r16 ;r16 auf 0 oder <> 0 testen
ret
.dseg
Text1: .db "ABC",0
Text2: .db "DEF",0
Wichtig ist die 0 nach jedem Vergleichstext im Data-Segment damit das
Textende ermittelt werden kann.
Läßt sich natürlich noch verfeinern wenn es darum geht, das auf ein
komplettes Wort geprüft wird und nicht z. B. nur auf "aus" wenn man
als Eingabe "aussetzer" schreibt.
Ich habe es weder assembliert noch auf Korektheit prüfen lassen da ich
mit nen AVR für so was noch keinen Gebrauch hatte.
Also bitte nicht lästern bei evtl. Fehlern.
Soll auch mehr als Denkanstoß dienen.
Gruß
Andi
Alternativ kannst du natürlich auch bei cmd_end1 direkt ein return
hinsetzen, würde ich aber nicht empfehlen. Funktioniert zwar, aber man
sollte es bei Unterprogrammen mit einem Ausgang genug sein lassen.
Wie bist denn darauf gekommen? ;-)
Mach es doch gleich als UP damit Du es auch für andere
Vergleichs-Strings verwenden kannst.
Am besten gleich so, dass das UP eine ganze Liste Befehle mit der
Eingabe vergleicht und hinter jedem Vergleichs-String gleich die
Adresse steht wo hin das UP dann springen soll.
z. B.:
.db "ABS",0,Jump1
.db "DEF",0,Jump2
Wenn Du das low-byte nach ZL und das high-byte nach ZH lädts
(wahrscheinlich über Umwege da Z der Pointer auf die Strings ist)
kannst Du dann mit dem Befehl IJMP (indirekt Jump jusing Register
Z-Pointer) gleich zu Jump1 oder Jump2 nach positivem Vergleich springen
lassen.
Viel Spaß noch beim basteln.
Gruß
Andi
Hi Andi,
> Mach es doch gleich als UP damit Du es auch für andere> Vergleichs-Strings verwenden kannst.
;-( puhhh das währe ja auch nicht schlecht.
Da es in der Tat mehrere Befehle sind.
Ich schlafe mal eine Nacht drüber.
Mal sehen vielleicht finde ich dann morgen raus wie man das macht.
Danke für den Tip... wieder was gelernt... :-)
Gruß AVRli...