Look-Up-Tabelle & Co.

Gast #21350
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
Gast #21353
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
Gast #21354
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 )
Gast #21355
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
#21356
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
Angehängte Dateien:
#21360
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
Gast #21361
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//
Gast #21362
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
Gast #21363
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
Gast #21364
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren