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.
Hallo nochmal, habe eine Lösung... die ist der vom Andi verdammt ähnlich. CMD_AZ: .db "ABC",0 SHOW_CMD_ABC: ldi ZL,low(CMD_ABC*2) ldi ZH,high(CMD_ABC*2) CMD_ABC_COMPARE: lpm mov T1,r0 cpi T1,0 breq CMD_ABCgo adiw ZL,1 ld T0,X+ cp T0,T1 breq CMD_ABC_COMPARE rjmp CMD_ABC_END CMD_ABCgo: ... Aktionen auf Befehl >63k ... CMD_ABC_END Funktionieren tut's... :-) Danke Euch für den Austausch! Gruß AVRli...
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...
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.