mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Noch weiter springen?


Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :)

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.