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
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
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
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 )
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
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
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
.. 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.
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.
@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
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//
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.