Forum: Mikrocontroller und Digitale Elektronik Datensätze mit oder ohne Sprungtabelle laden? [AVR8 Assembler]


von int 21h (Gast)


Lesenswert?

Hallo,

ich arbeite gerade an einer Routine, mit der man einzelne Buchstaben 
(ASCII) auf ein OLED darstellen kann.

Nun ist die Frage, wie ich die einzelnen Datensätze für die jeweiligen 
Buchstaben laden sollte.
Wären dass nur wenige Zeichen (z.B. 10-20), dann wäre eine Sprungtabelle 
dafür angebracht, aber bei über 100 Zeichen bietet sich sicher eine 
bessere Lösung an.
Oder was meint ihr dazu?

Option 1 (Sprungtabelle):
1
;Zeichne Buchstabe 'A'
2
    ldi   temp1, A
3
4
...
5
6
ldi   ZH, HIGH(jumptable * 2)
7
ldi   ZL, LOW(jumptable * 2)
8
add   ZL, temp1
9
ldi   temp1, 0
10
adc   ZH, temp1
11
ijmp
12
13
;Sprungtabelle (> 100 Verzweigungen, viel Laufzeit, viel Code)
14
jumptable:
15
    rjmp load_A
16
    ...
17
    rjmp load_Z
18
19
load_A:
20
    ldi   ZH, HIGH(A * 2)
21
    ldi   ZL, LOW(A * 2)
22
    ;loop 5 mal
23
    LD    temp1, Z+
24
    rcall twi_send_byte ;Sende ein Byte an das OLED
25
    ...
26
    rjmp  back
27
28
;ASCII
29
A:
30
    .DB 0x8A, 0xA3 ;Nur als Beispiel
31
    .DB 0x25, 0x25
32
    .DB 0x8A
33
...
34
Z:
35
    .DB 0x8A, 0xA3
36
    .DB 0x25, 0x25
37
    .DB 0x8A
38
...

Option 2 (ohne Sprungtabelle):
1
;Zeichne Buchstabe 'A'
2
    ldi   temp1, A
3
4
...
5
6
ldi   ZH, HIGH(ascii * 2)
7
ldi   ZL, LOW(ascii * 2)
8
ldi   temp2, 5
9
mul   temp1, temp2
10
add   ZL, temp1
11
ldi   temp1, 0
12
adc   ZH, temp1
13
rcall oled_draw_char
14
ijmp
15
16
ascii:
17
;A
18
    .DB 0x8A, 0xA3 ;Nur als Beispiel
19
    .DB 0x25, 0x25
20
    .DB 0x8A
21
...
22
;Z
23
    .DB 0x8A, 0xA3
24
    .DB 0x25, 0x25
25
    .DB 0x8A
26
...
Zu Option 2: bei über 100 Zeichen (100 * 5 bytes), passen die Werte zu 
den Adressen nicht mehr in den temp1 Register.
Genauso wenig lässt sich ZH mit einem einfachen add carry korrekt laden.
Wie würde man das anstellen falls diese Variante die bessere ist?

von Karl M. (Gast)


Lesenswert?

Hallo,

ich würde mir eine Tabelle (Array) mit den Adressen (Pointer) der 
Speicherorte jedes einzelnen Zeichen im Flash-Speicher (ProgmeM) 
anlegen, fertig.

Die Tabelle könnte dann für Zeichen ab ' ' (blank) auf die 
Zeichendefinition verweisen.

von Peter D. (peda)


Lesenswert?

int 21h schrieb:
> Zu Option 2: bei über 100 Zeichen (100 * 5 bytes), passen die Werte zu
> den Adressen nicht mehr in den temp1 Register.

Kein Problem, MUL ergibt 16 Bit, das Produkt steht in R1:R0.
1
add zl, r0
2
adc zh, r1

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>ldi   temp2, 5

Das funktioniert nicht.

weil
>    .DB 0x8A

eine Warnung erzeugt:  warning: .cseg .db misalignment - padding zero 
byte

und

.DB 0x8A, 0x00

daraus macht. .DB-Zeilen müssen immer geradzahlige Anzahl von Bytes 
aufweisen. Also kannst du gleich

    .DB 0x8A, 0xA3, 0x25, 0x25, 0x8A, 0x00

schreiben

MfG Spess

von S. Landolt (Gast)


Lesenswert?

... oder zum Beispiel immer zwei Zeichen in einer Zeile zusammenfassen, 
dann kann man bei 5 bleiben.

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.