www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sprungtabelle


Autor: Christoph Wolthaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab folgendes Problem:

Abhängig von einem BYte soll ein entsprechendes Programm ausgeführt
werden:
Bisher mache ich das so:
byte --> r16

cpi r16,0x00
breq prg0jmp
cpi r16,0x01
breq prg1jmp
...

prg0jmp:
rjmp prog0
prg1jmp:
rjmp prog1
...
prog0:
 //code

prog1:
//code

Das muss aber viel viel einfacher gehen mit ijmp oder so etwas.
Hat da jemand ne elegante Lösung für mich?

Autor: Christoph Kessler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
skip if bit set...
rjmp
rjmp

ist der Code so lang, dass der branch nicht reicht?

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, wenn du die absolute Adresse von deiner Sprungtabelle im Register Z
hast (
  ldi  ZL,low(prg0jmp*2)    ; low
  ldi  ZH,high(prg0jmp*2)    ; high
), dann geht es bisschen einfacher:

  add zl, r16
  brcc no_carry
  inc zh
no_carry:
  ijmp

Autor: Christoph Wolthaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JA der ist zu lang. Und mit deinem Vorschlag kann ich zunächst auch nur
8 Programme ansteuern. ODER ? Dachte an sowas wie

(i)jmp label + r16 * (länge vom rjmp)

Label:
Rjmp prog0
Rjmp prog1
Rjmp prog2
Rjmp prog3
Rjmp prog4

nur ich würde ganz gerne einer multiplikation aus dem weg gehen.

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bemerkung:
mit zl sollst du erst LSL machen (mal 2)

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falsch! lsl r16 - so soll es sein

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder so:

menujump:               ;Menüpunktaufruf
 ldi zl,low(menujmp)        ;Zeiger auf Sprungtabelle
 ldi zh,high(menujmp)
 add zl,mp                  ;Menüpunkt
 adc zh,null                ;dazu
 ijmp                       ;Menüpunkt aufrufen


menujmp:                ;Menü-Sprungtabelle
 rjmp mp_00
 rjmp mp_01
 rjmp mp_02
 ...

mp_00:                  ;Hauptmenü, Ebene Edit
 sbrc flags,v24rx           ;PC-Verbindung aktiv? nein...
 rcall usart_aus            ;ja, deaktivieren...
 mov ztl,ff                 ;Uhr auf
 mov zth,ff                 ;-1
 cbr flags,1<<aktiv         ;und aus
 rcall testmax              ;Anzahl Schüsse ermitteln
 rjmp editliste             ;Liste aufbauen und Menütexte anzeigen


Alles im Zusammenhang hier zu sehen:
http://www.hanneslux.de/avr/zuenduhr/ZndUhr01.asm

...

Autor: Christoph Wolthaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DRei fragen an Aleksej:
a)
wofür die multiplikation mit zwei?
b)
reicht es den Wert von Z einfach mit meinem Inhalt von r16 zu erhöhen?
oder muss ich die länge eines rjmp-Befehl noch multiplizieren
c)
meine tabelle sähe dann so aus?:
prg0jmp:
rjmp prog0
rjmp prog1
rjmp prog2

Autor: Christoph Wolthaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry ihr seit mir zu schnell!

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Multiplikation mit 2 ist für byteweisen Zugriff bei LPM
erforderlich, bei IJMP aber nicht, da hier der Zugriff wordweise
erfolgt.

...

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> sorry ihr seit mir zu schnell!

Wir sind auch Mehrere, du nur Einer...

Wir teilen uns quasi die Arbeit...

;-)

...

Autor: Christoph Kessler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Baumartig verzweigen:
cpi $80
brge...
cpi $40
brge...
cpi $20
das ist jedenfalls schneller als 255 Vergleiche nacheinander, nach 8
Vergleichen hat man 256 Sprungziele erreicht

Autor: Remo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht auch einfacher mit IJmp oder ICall.
Aufpassen: diese Befehle können manche AVR Controller nicht, also
besser vorher im Datenblatt nachschlagen.

Im Prinzip funktioniert das so (habs die Syntax nicht ausprobiert):

; Sprungtabelle in Z-Pointer laden
   LDI ZL, low(Sprungtabelle)
   LDI ZH, high(Sprungtabelle)
;hier musste nochmals nachschlagen das Prinzip sollte klar sein, der
Assembler soll das low byte der Adresse der Sprungtabelle in ZL laden
dito für ZH, die Syntax sieht bestimmt ein bischen anders aus.

; Nachdem jeder Eintrag in der Sprungtabelle 2 byte gross ist musst du
den Index-Wert in R16 noch mit 2 multiplizieren das enspricht einem
linksshift.
   LSL R16
;Nun index auf Z draufaddieren (auf überlauf des lowbyte achten!)
; daher vorher ein Register mit 0 laden
   SUB R0,R0      ; R0 wird mit 0 geladen
   ADD ZL, R16    ; R16 wird auf ZL addiert und C ggfs. gesetzt
   ADC ZH, R0     ; ZH = ZH + 0 + C, ggfs carry draufaddieren. zum
Registersparen geht das auch ohne R0 mit Abfrage des Carrybits und
einem eventuellen INC des ZH.

; Nun der eingentliche Sprung
   Ijmp
; Hier nun die Sprungtabelle
Srungtabelle:
   rjmp prog0
   rjmp prog1
   rjmp prog2
   ....

ciao
Remo

Autor: Christoph Wolthaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HEY HANNES!!
Genau das isses! Alles Befürchtugen sind dahin, das funzt! Danke an
Euch alle!

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.