mikrocontroller.net

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


Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: wolli_r (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

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

Autor: Sebastia (Gast)
Datum:

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

Autor: Sebastia (Gast)
Datum:

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

Autor: crazy horse (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

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

Autor: Sebastia (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

Autor: Sebastian Wille (Gast)
Datum:

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

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.