Forum: Mikrocontroller und Digitale Elektronik Look-Up-Tabelle & Co.


von Sebastian Wille (Gast)


Lesenswert?

Hallo,

ich steuere im Moment ein Grafik-Display an. Dort sind keine 
ASCII-Zeichen definiert, also habe ich mir sämtliche ASCII-Zeichen 
selbst gebastelt. Das funktioniert auch wunderbar.

Das Problem: Der Speicher. Im Moment benötigen alle Zeichen ca. 12 KB. 
Das ist viel zu viel für meinen 2313. Ich habe für jedes Zeichen eine 
eigene "Prodzedur", also recht uneffizient.

Jedes einzelne ASCII-Zeichen besteht aus 6 Byte. 256 Zeichen x 6 Byte 
macht also 1536 Byte.

Nun meine Idee: Ich möchte irgendwo einen speziellen Speicherbereich 
haben (z.B. 0x0300) und ab da stehen einfach alle 
ASCII-Zeichen-Definitionen nach einnander. Möchte ich also das 
ASCII-Zeichen 3, so lese ich die Speicherstellen 0x0312-0x0317. Das 
denke ich, müßte das Platzsparendste sein.

Natürlich könnte ich auch einen Mega nehmen, das wäre aber a) zu teuer 
und b) Verschwendung.

Noch eine kleine Frage nebenbei: Wenn der AVR-Compiler sagt, mein 
Programm habe 390 Worte, sind das dann 780 Byte Speicherplatz?!?

Vielen Dank!

   Sebastian

von Sebastian Wille (Gast)


Lesenswert?

Hallo,

oder weiß vielleicht jemand, was genau eine Look-Up-Tabelle ist und wie 
man sie verwendet?!?

Ich wär' Euch echt dankbar!

Grüße,

   Sebastian

von Christian (Gast)


Lesenswert?


von Sebastian Wille (Gast)


Lesenswert?

Hi Christian,

danke für den Link! :-)

Leider hat mir das noch nicht wirklich weitergeholfen. Ich will nichts 
mit dem EEPROM machen (eh zu klein).

Weiß denn niemand wie man eine Lookup-Tabelle in Assembler 
programmiert?!?

Und könnte mein Trick mit der Speicheradresse (siehe oben!) nicht 
funktionieren?!?

Ich brauche Eure Hilfe! Danke!!!

Sebastian

von wolli_r (Gast)


Lesenswert?

Hi,
da ohnehin um "Read only" Daten geht und Du für
einzelne Pixelansteuerung auch einigen Platz
brauchst, empfehle ich ein I2C EEPROM wie das 24C64 oder 24C128. So ein 
Baustein ist relativ schnell
auszulesen (wenns nur ums Lesen geht) und die
Ansteuerpins belegen auch nur 2 Portleitungen.

mfg wolli_r ( www.tec-shop.de )

von Sebastian Wille (Gast)


Lesenswert?

Hi wolli_r,

danke erstmal für die Antwort! :-)

Die Idee ist nicht schlecht und notfalls werd ich's auch so machen. Nur 
wollte ich so wenig externe Komponenten wie möglich verwenden 
(Platzproblem trotz SMD).

Der interne Speicher sollte ja auch reichen. Gibt es denn keinen Befehl, 
der sagt "springe zu 0x468"?!?

Danke!

Sebastian

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Ich glaube, da mußt Du in Assembler programmieren, um alles in 2kB zu 
quetschen.
In C kann man auch Tabellen auslesen, aber da ist der Overhead zu groß.

Ich hab mal eine LED-Zeile (16*5*7) mit nem 2313 angesteuert, die 2kB 
sind zum bersten voll.

Anbei die Routine zum Auslesen eines Zeichens in den Display-RAM.


Peter

von Sebastia (Gast)


Lesenswert?

Hallo, ich mache es immer so

Daten:
.db 255,128,88,77
.db 88, 56, , 44,41
.
.
.


dann gibt dir Lpm die Daten zurück für die adr. die im Z-Pointer steht.

ldi ZH,high(Daten*2)
ldi ZL,low(Daten*2)
Lpm
;; in r0 steht jetzt 255
wenn du den z+ nimmst und wieder lpm ausführst steht in r0 128 ....

MfG
Sebastian

von Sebastia (Gast)


Lesenswert?

.. nachtrag,

wenn du jetzt Einzelne grupen definieren willst brauchst du ja nur noch 
relativ zu "Daten" de Offsets angeben und dann zum Z Pointer zu 
addieren.

von crazy horse (Gast)


Lesenswert?

flash unsigned char ascii_tab[30,6]={{x,x,x,x,x,x},
                                      {x,x,x,x,x,x},
                                       usw
                                       };
ergibt eine Tabelle für 30 Zeichen mit je 6 Byte, nix mit großem 
overhead.

von Peter D. (peda)


Lesenswert?

@verrücktes Pferd,

stimmt, nur die Tabelle allein bringt keinen großen Overhead.

Das sind die einzelnen Unterfunktionen, die soviel Platz benötigen.
Außer dem profanen Schreiben eines Zeichens an eine bestimmte Stelle hab 
ich noch das Reinscrollen von rechts, links, oben, unten, für einzelen 
Zeichen oder Pixel oder Texte.

Ich hab das z.B. als Uhr, wo die Ziffern einzeln von oben runterfallen, 
etwas zutief und dann wieder zurückschnappen.

Dann noch eine Art Interpreter, d.h. die Texte und die Kommandos, wie 
diese darzustellen sind, kommen über die UART von dem Haupt-MC.

Und damit habe ich in Assembler den Rest der 2kB völlig zugestopft.

Der RAM ist dabei nur Bildspeicher und Eingabepuffer, alle anderen 
Variablen sind ausschließlich in den 32 Registern.

Teilweise sind die Register einzelnen Funktionen exclusiv zugeordnet um 
selbst an PUSH und POP soviel wie möglich zu sparen.

Ein 20-Pinner mit 8KB wie die von Philips wäre wirklich dringend nötig.


Peter

von Sebastia (Gast)


Lesenswert?

Hallo,

wenn du die Tabels für die zeichen schon im AVR hast , sollte es doch 
kein problem sein wenn man die daten geschickt anordnet mit einer 
kleinen rechenroutine ein pixelgenaues scrolling oder moving zu 
realiesieren du musst halt mit variablen offsets in den bitmasken der 
zeichen arbeiten. genauso für das erzeugen der zeichen,.. wenn man zb. 
bar graphen erzeugt kann man die ausrechen und zr laufzeit erstellen da 
brauch man nur etwas rechenleistung und geht unter umständen sogar etwas 
schneller, is aber mit mehr denksport verbunden.

Aber 2kb sind doch etwas arg wenig für deine aufgaben, und ein größerer 
avr is ja auch nicht unbedingt teuer.


MfG
Sebastian

//www.mcu-design.de//

von Sebastian Wille (Gast)


Lesenswert?

Hallo,

danke erstmal für alle Antworten!!! :-))

@Peter: Das sieht genau nach dem aus, was ich mir vorstelle! Kannst Du 
eventuell das ganze Programm posten?

@Sebastia(n): Perfekt! Ich möchte auf alle Fälle sowieso in Assembler 
bleiben. Notfalls nehm' ich auch einen 4433, an dem soll's auch nicht 
liegen. Ich möchte nur keine 14KB vollknallen, denn die 
Display-Ansteuerung macht nur einen kleinen Teil des kompletten 
Programms aus.

Ich werd' das ganze nun mal ausprobieren und melde mich dann wieder.

Auf alle Fälle schonmal vielen Dank!!! :-)

Viele Grüße,

   Sebastian

von Sebastian Wille (Gast)


Lesenswert?

Hi Sebastian,

nochmal eine kurze Frage zu Deinem Beispiel.

Also:

ldi ZH,high(Daten*2)
ldi ZL,low(Daten*2)
Lpm

gibt mir 255.

Was genau heißt Z+?

ldi ZH,high(Daten*2)+1
ldi ZL,low(Daten*2)+1
Lpm

?!?!?!?!?!?!?

Und wie spreche ich die 2 Zeile (also .db 88, 56, , 44,41) an?!?

Und warum eigentlich "Daten*2". Das heißt ja glaube ich nicht wirklich 
"mal 2" oder?!?

Vielen Dank schonmal! :-)

Sebastian

von Sebastian (Gast)


Lesenswert?

Hallo,
das "n" hatte ich irgendwie immer in meinem namen übersehen g.

Z+ heisst
adiw    ZL,1                    ;16-Bit Zeiger erhoehen

oder inc 16bit pointer +1

>>Und wie spreche ich die 2 Zeile (also .db 88, 56, , 44,41) an?!?

das.. ist im Flash immer fortlaufend also Wenn du 10 byte unter daten 
hast kannst du auf das letzte byte mit Daten +9 zugreifen.
bsp:
Daten:
.db 1,2,3,4
.db 5,6,7,8
Daten2:
.db 11,12,13,14
.db 15,16,17,18

um auf 6 zugreifen zu können musst du die adr Daten+5 nehmen.
wenn du auf 18 zugreifen willst musst du halten Daten2+7 nehmen.

an die daten also zaheln kommst du mit LPM , das die adr. aus dem 
Z-Pointer im vom Flash in r0 lädt.

so jetz mal zu dem hier:
>ldi ZH,high(Daten*2)
>ldi ZL,low(Daten*2)

da das ja alles wor basiert ist muss man ja irgendwie die einzelnen 
bytes adressieren.
wenn vom Z Pointer das LSB 0 ist wird das low byte geladen bei 1 das 
high byte ( der speicher ist ja wortorientiert)
also Z * 2 = 1 mal schieben nach links <=> LSB wird null
!! das ist aber nur bei LPM so !!
beim high byte: ldi ZL,(Daten*2+1);
.. steht aber alles im datenblatt oder ?


so sollte der code aussehen wenn man ein daten segment laden will:

LoadStartPointer:
  ldi ZH,high(Daten*2)
  ldi ZL,low(Daten*2)
Loop:
  LPM
  adiw ZL,1
  <abbruchbedingung>   // lade so lange Z in r0 bis break erreicht ist
  rjmp Loop


ich hoffe ich habe jetzt nichts falsches gesagt, aber bei mir hats immer 
funktioniert.

MfG
Sebastian
www.mcu-design.de

von Sebastian Wille (Gast)


Lesenswert?

Hallo Namensvetter,

danke für die Erklärung! :-)

Also nun läuft das ganze in Ansätzen schon bei mir.

Aber kann es sein, daß der Wert "0" nicht gespeichert werden kann?!? Der 
klappt bei mir nämlich nicht. Und im Datenblatt finde ich die 
Lookup-Tabellen nicht.

Danke!

Sebastian

von Sebastian Wille (Gast)


Lesenswert?

Hallo nochmal!

Also: Es hat sich geklärt. Es lag einfach daran, daß eine über die 
serielle Schnittstelle gesendete "0" (als ASCII-Wert) nicht angezeigt 
wird.

Vielen Dank nochmals!!!

Sebastian

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.