Also ich habe hier einmal einen Beispielcode zum Initialisieren des Displays, der meiner Ansicht nach mindestens einen Punkt ausgeben sollte: http://www.freak5mynew.no-ip.info/Muell/DatenBlatToshibaTLX1391BSP.gif Dabei habe ich dese Möglichkeit noch nicht einbezogen, welche aber anscheinend nur eine andere Möglichkeit zum Setzen eines Punktes ist. DatenBlatToshibaTLX1391-BSP.gif Verbunden ist das Display so: http://www.freak5mynew.no-ip.info/Muell/Pinbelegung.txt Und aus meiner Verzweifelung habe ich mein Programm sogar ganz ohne Schleifen usw. noch einmal programmiert, wobei ich den Initialisierungscode abgeschrieben habe: http://www.freak5mynew.no-ip.info/Muell/DisplayansteuerungGanzVereinfacht.txt Die Kontrastspannung kann ich ändern und Sttom ist auch auf der Leitung. Einen Reset führe ich ja auch durch. Der Controller ist ein Atmega16 und das Display ist ein TLX1391 von Toshiba mit einem SED Controller. Ich komme einfach nicht auf meinen Fehler. Besonders, wo das Display selbst nach dem Beispielcode gar nichts anzeigt. Die gesampte Beschreibung kann man sich bei Pollin herunterladen. ich bin über jede Erkenntnis dankbar. Ich finde den Fehler aber einfach nicht.
Gibt es in solchen Situationen eigentlich hilfen zum Debugging, die einem schnell und einfach zeigen, ob es am Display liegt, an der Verkabelung(eher weniger) oder am Programm?
Ich kenne zwar Dein LCD nicht, aber braucht es wirklich so lange um die Daten anzunehmen das Du eine Verzögerungsschleife zwischen SBI und CBI setzen mußt? In der Regel reichen ein paar NOP´s, wenn überhaupt, oder es braucht je nach LCD-Typ auch nichts zwischen SBI und CBI gesetzt zu werden. Bei meinem geht das z. B. auch so: out lcd_port,r16 ;Daten (4 Bit) zusammen mit Enable-Bit ausgeben. cbi lcd_port,EN ;Enable löschen. Verlänger doch lieber die Warteschleife zwischen der Daten- und Comandoausgabe wobei mir diese auch schon seeehr lange vorkommt (habe nicht nachgezählt). Und denke daran, das ein Löschbefehl (LCD-Clear (CLS)) am längsten an Zeit benötigt (steht bestimmt im Datenblatt). Ach ja: Bei verwendung von Port C solltest Du das JTAG mit den Fuses abschalten sonst ist an Port C keine normale Port-Funktion. Wie das geht steht im Mega16-PDF im Abschnitt "Memory Programming". MfG Andi
"sonst ist an Port C keine normale Port-Funktion." Davon habe ich bis jetzt noch nichts bemerkt. Ich werde mir das durchlesen, aber könnte das den Fehler verursachen?
Wenn das LCD die selben Leitungen wie das JTAG benutzt und dieses nicht per Fuse ausgeschalten ist, kann es nicht funktionieren, da die Port-Ausgänge dann nicht mit den eigentlichen Pins verbunden sind. Deshalb sind bei mir die JTAG-Leitungen die letzten, die ich bei der Verteilung der Anschlüsse "verbrate", da mann sich damit die Möglichkeit des JTAG (Prgrammieren, debuggen) verbaut. Jörg
"Ach ja: Bei verwendung von Port C solltest Du das JTAG mit den Fuses abschalten sonst ist an Port C keine normale Port-Funktion. Wie das geht steht im Mega16-PDF im Abschnitt "Memory Programming"." Ja aber mit dem Multimeter habe ich die richtigen Ausgangswerte an Port C, wie kommt das denn? Oder ist dieses JTag irgendwie hochfrequentig und kann so mit dem Multimeter nicht ausgelesen werden? Bei einigen Pins schien das Multimeter aber TriState anzuzeigen. Ich habe das als 0V ausgelegt, aber ich überprüfe das mal....
Setzt das JTAG-Fuse auf unprogrammed um mal einen Schritt weiter zu kommen. Ging mir mal genauso für ne PWM und was war, NIX regte sich an PC7 solange JTAG aktiviert war. MfG Andi
Ichhabe das Fusebit einfach gelöscht(Ponyprog). Verändert hat sich nichts(30sek beobachtung) Ich muss jetzt los. Vielleicht finde ich heute nachmittag noch etwas Zeit...
Es handelt sich also nur um PC7? Ich werde das in ein paar Stunden überprüfen. Danach kommen die Timings dran! Ich sitze an dem Display schon seit Ostern :-(. Vorher war es aber die Ansteuerung über ein Schiftregister, welche nun funktioniert. Jetzt erst bemerke ich, dass das richtige Problem das Display ist.(deshalb ja die Direktansteuerung und der einfache Code)
Nei, es handelt sich um PC5 bis PC7, evt. noch um PC4. Das mit PC7 war nur ein Beispiel. MfG Andi
Ich habe das Bit deaktiviert und die Wartezeiten habe ich verdoppelt bis verachtfacht. es zeigt sich immer noch keine Reaktion auf dem Display :-(
Jetzt habe ich ein Muster auf dem Display, welches immer ähnlich ist, aber jedesmal etwas anders. Es ist wie aus einem Grundmuster zufällig generiert und erscheint, wenn man die Spannung für das Display aufdreht!
Das Muster kommt aber erst nach dem Reset und anscheinend erst, nachdem das gesampte Programm durchgelaufen ist. Hier nocheinmal die aktuelle Version: http://www.freak5mynew.no-ip.info/Muell/DisplayFehlMuster.txt Und das hier habe ich zusätzlich abgetippt, was anscheinend das Muster verursacht. Eigentlich dürfte es doch gar nicht erscheinen und schon gar nicht zufällig.... http://www.freak5mynew.no-ip.info/Muell/DatenBlatToshibaTLX1391-BSP.gif
Ich nehme mal an, dass du JTAG inzwischen deaktiviert hast und dein Port nun korrekt funktioniert. Dem Foto nach könnte das ein Grafik-LCD (128x128 Pixel) mit Controller T6963 sein. Dies wird etwas anders angesprochen als die üblichen Displays mit HD44780-Controller. Vor etwa einem Jahr habe ich mal mit einem 240x128-Pixel-LCD mit T6963 und einem Mega8 gespielt. Der Code ist zwar nicht besonders, aber er funktioniert. Vielleicht hilft es ja, wenn du ihn mal analysierst. ...
Mh ich habe deinen Code noch nicht ganz verstanden. Hast du da gar keine Konstanten drin? Und zum JTaG ich habe das einfach mal wieder eingeschaltet. Das Ergebnis ist, dass das Muster jetzt auch noch blinkt. Irgendwie muss das mit dem Beispiel doch nicht so hinhauen :´-( Gibt es irgendwo Tuts für diesen Chip? Ich gehe ja davon aus, das mein Datenblatt wenigstens die richtige Pinbelegung beschreibt. Dann könnte ich ja einfach den Beispielcode von irgendeinem andern Display ausgeben lassen um die Verkabelung zu testen und den Rest kriege ich, wenn erst mal ein Punkt da ist sicher auch hin....
Das ist eigenartig. Ich habe den Atmel herausgezogen und das Muster wandert immer noch, ohne dass ich etwas berühre...
Mh der Code scheint irgendwie falsch zu sein(meiner) Ich habe den Zusatzcode mal wieder weggemacht und jetzt bekomme ich einfach nur ein Muster auf PIxelbasis und nicht mehr auf 8x8 Pixelbasis. Ich muss mein Programm wohl noch einmal debuggen.
Das Muster kommt vermutlich daher, dass Unsinn im Display-RAM steht (falls es sich um ein Display mit Controller T6963 handelt). Eigentlich wird es jetzt mal Zeit, die Spekulation zu beenden. Teile bitte mal mit, welchen Controller dein LCD hat. Denn jeder Controllertyp wird anders angesteuert. Es kann gut sein, dass wir alle aneinander vorbei reden. Meine Konstanten sind übrigens in der Include-Datei definiert. Das war ein erster Versuch, die LCD-Routinen als (wiederverwendbares) Modul zu isolieren. Ist vielleicht nicht so gut geraten, aber Jeder fängt mal an. ...
Noch vergessen: Hast du ein JTAG-Interface und benutzt du dieses zum Debuggen?? Falls nicht, dann solltest du JTAG dauerhaft deaktivieren. ...
?? Wie kann man das dauerhafter als mit den Fuses deaktivieren? Ich weiß bis jetzt noch nicht, wie ich JTag nutzen kann, also ist mir das INterface eigentlich egal. P.S.: Mh mir ist mein Präzisionssockel kaputt gegangen. Jetzt muss ich einen normalen verwenden. Für die Teile sollte man echt mal einen 0Kraft Sockel anbieten...
Mist das Datenblatt ist vorhin nicht ganz herübergekmmen. Ich habe es jetzt gesplittet.
Ich habe hier noch einen INteressanten Abschnitt gefunden: (Das Datenblatt ist dumm, da es nur eine Kopie ist, die in das PDF-Format gepresst wurde :-( ) It is necessary tu guard all signals from external noise as signal lines are directly connected to C-MOS and are not pull-up or pull-down internally excluding RESET which is pull-up to VDD Bedeutet das, dass ich vielleicht etwas falsch gemacht habe mit dem Gewusel auf der Rückseite der Platine? Auf dem Foto hat man vielleicht noch ein paar lose Stränge gesehen!
... oder ZIFF-Sockel! Hebel auf, Controller reinfallen lassen, hebel zu und andersrum mit 0 Kraft wieder raus. Braucht halt ein bißchen mehr Platz. MfG Andi
Für die Entwicklung ist es egal. Ich möchte nicht immer Löcher in den Fingern haben :-( Der Controller ist ein LSI T6963C !
Also das TLX1391 von Pollin (128x128 Pixel). Das Datenblatt habe ich dann auch hier. Allerdings habe ich mir dieses LCD nicht gekauft, da es mir etwas teuer erschien und ich einige 240x128 Pixel-LCDs habe. Dass die Datenblätter etwas unsauber sind (gescanntes Papier) hat damit zu tun, dass sie schon etwas älter sind und man damals noch mehr mit Papier und weniger mit dem Computer gearbeitet hat. 40-polige Nullkraft-Sockel gibt es bei Pollin. Leider verpacken die die sehr schlecht, wodurch die Pins verbiegen bzw. abbrechen. Auf meine Beschwerde haben sie mir die nochmal geschickt, wieder 5 Stück in eine Folientüte geschmissen und wieder einige kaputt. Nun habe ich sie zerlegt, die Pins (Kontaktfedern) getauscht und wieder zusammengesetzt. JTAG kann man mit der Fuse dauerhaft deaktivieren. Man kann es aber auch mit Programmcode deaktivieren. Das ist dann nicht dauerhaft. Da man mit den Fuses viel Unheil anrichten kann, halte ich mich mit dem Vorschlag, die Fuses zu ändern, etwas zurück. Das Bild im Anhang zeigt eine Testplatine mit Mega8 und dem oben genannten LCD, auf dem das oben gepostete Codebeispiel läuft. Auf die Testplatine ist ein MAX232 gesteckt, alternativ kann die links zu sehende Ladungspumpe gesteckt werden (der Code unterstützt die Ladungspumpe). Ladungspumpe oder MAX232 erzeugen die negative Kontrastspannung für das LCD. Da ich den Mega8 ohne Quarz betreibe, haut die V.24 nicht hin. Daher habe ich das Projekt verworfen und werde es irgendwann mal mit einem Mega16 (mehr I/O) und Baudratenquarz versuchen. ...
Ich dachte das Display sei günstig. Vor allem, wo ich sonst kein Display unter 70E gesehen habe. Ist an einer Ladungspumpe irgendwas besonders? Ich habe einen LT1054 benutzt, so wie es auch auf www.modding-faq beschrieben wird. Wenn ich das beschreiben sollte würde ich das auch als Ladungspumpe beschreiben, da ein Kondensator geladen wird und mit dieser Ladung die negative Spannung entsteht. Warum muss diese mit dem Controller verbunden werden? Kann deine Version diese Spannung regeln? "mir etwas teuer erschien und ich einige 240x128 Pixel-LCDs habe." Woher hast du diese Displays denn bekommen?
Wofür brauchst du so viele Elkos? Ich hätte höchstens 3 Verwendet. Einen zum Stabilisieren der Eingangsspannung, einen für den Inverter und einen zum Stabilisieren der negativen Ausgangsspannung. Da sind aber zwei weitere auf der Platine. "JTAG kann man mit der Fuse dauerhaft deaktivieren" So dauerhaft ist das ja auch nicht. Es läuft nur bis zum nächsten Beschreiben. So problematisch sehe ich das auch nicht an, da man ja die standartwerte einfach laden kann und dann nur aufpassen muss, dass man nur ein Fuse ändert. Ich sehe das umstecken meines Controllers als gefährlicher an. Besonders weil ich mich dabei zu 10% verletze(ich sollte vielleicht einen Fingerhut tragen) "Dass die Datenblätter etwas unsauber sind (gescanntes Papier) hat damit zu tun, dass sie schon etwas älter sind und man damals noch mehr mit Papier und weniger mit dem Computer gearbeitet hat." Wie alt ist das Display denn nun? So wie du das jetzt beschrieben hast hört sich dieses Display richtig antig an. Ich habe mich schon gewundert, dass Google eigentlich nichts darüber ausgibt. Toshiba kennt das auf der HP auch nicht und auf Mails, die sich darauf beziehen habe ich auch keine Antwort bekomen. Werden solche Displays überhaupt noch hergestellt?
Das Display ist dann günstig, wenn man nix Anderes hat. Ich habe aber einige dieser großen LCDs bekommen, weil ich mal einer Firma, bei der ein Freund arbeitet, den Tip gab, ihre nicht mehr benötigten LCD-Lagerbestände an Pollin zu verkaufen. Die großen wurden mangels ausreichender Stückzahl abgelehnt. Daher bekam ich sie als Dankeschön. Die Ladungspumpe ist eine 2-stufige Villard-Kaskade, besteht also aus 4 Elkos und 4 Dioden. Sie wird von einem AVR-Pin angesteuert, der in der Timer-ISR getoggelt wird. Sie ist nicht regelbar und erzeugt etwa -9,3V, was einen brauchbaren Kontrast erzeugt. Die Modding-Seite kenne ich nicht, Modderei ist nicht mein Ding. Für ein 8x24-LCD mit M50530-Controller habe ich eine ähnliche Ladungspumpe mit CD4093 als Taktgeber im Einsatz. Das Umstecken des Controllers ist zwar nicht besonders gefährlich, aber recht lästig. Deshalb haben meine Testplatinen meist einen ISP-Anschluss. Beim Mega16 (Mega32, Mega8535) ist dies besonders einfach, da alle für ISP erforderlichen Pins direkt nebeneinander in einer Reihe liegen. Dort kommt daher eine 6-polige Buchsenleiste zum Einsatz. Damit wird der Controller in der Zielschaltung programmiert. ISP heißt ja nicht umsonst "In System Programming". Falls sich das Wechseln nicht vermeiden lässt benutze ich einen verbogenen Schraubendreher als "Brechstange" zum aushebeln. Das schont Pins und Finger. Die Displays sind schon etwas älter. Es sind schließlich Restposten. Allerdings waren sie als Qualitätsware für industriellen Einsatz im erweiterten Temperaturbereich mal recht teuer, es ist also kein Ramsch. Oben erwähnte Firma baut Visualisierungen für industrielle Steuerungen. Statt dieser Displays werden inzwischen große Farbdisplays eingesetzt, teils mit Touchscreen. ...
Mh soweit lässt sich dann sagen, dass die Fehler zu 99% durch meine Ansteuerung verursacht werden, oder?
Nun, es ist unwahrscheinlich, dass es der Fehler von Bill Gates ist. :) Geh' doch nochmal alles durch: - Pinbelegung (vielleicht sind ja Bits am Datenport verdreht?) - kalte Lötstelle (o.Ä.) an einer Datenleitung? - interne Pull-Ups aktiviert? - korrekte Initialisierungs-Sequenz (Datenblatt Seite 28)? - korrektes Einlesen des Statusbytes? Vergleiche doch einfach mal deine Initialisierung mit meiner. Wegen der Übersichtlichkeit habe ich meine Dateien mal zu einer Datei zusammenkopiert, somit hast du alles lesbar in einer Datei (auch die Konstanten). ...
Könnte sich diese Muster eigentlich auch daraus ergeben, dass ich nur 2 Pixel setze und dann das Display aktiviere? Schreibt das Display den gesampten Speicher nicht auf 0, nachdem ein Reset durchgeführt wurde?
"- korrekte Initialisierungs-Sequenz (Datenblatt Seite 28)?" Das ist das einzigste, was ich bis jetzt abgetippt habe. Das ist ja auch für das Muster verantwortlich. Könnte dieses Muster dadurch entstehen, dass unbeschriebene Pixel zufällig sind? Aber eigentlich müsste da irgendwo auch ein Buchstabe sein....
Ach du benutzt als Konstante gar keine Binärangaben, sondern dezimale... Jetzt habe ich sie gefunden. Pull ups? Ich dachte, das wäre nur bei Eingängen wichtig? Ich habe an den Einstellungen wie man am Code sehen kann nicht herumgefummelt....
Vergiss die Pixel und beschränke dich erstmal auf die Ausgabe von Text unter Benutzung des CG-ROM des LCD. Wenn das alles funktioniert, dann kannst du über Grafik nachdenken. Die Muster ergeben sich daraus, dass das LCD nicht richtig initialisiert wurde und Zufallswerte im RAM des LCDs stehen. Um diese zu löschen, müssen die Areas korrekt gesetzt werden. Dann ist der gesamte Speicher mit 0 zu überschreiben, um die Muster zu überschreiben. Dies macht bei mir diese Routine: gcls: ;gesamten RAM im LCD löschen ldi r17,0 ;RAM-Beginn rcall w_dat ldi r17,0 rcall w_dat ;$00 und $00 in ldi r17,$24 ;Adress-Pointer rcall w_cmd ;setzen ldi zl,low($2000) ;Zähler auf gesamtes LCD-RAM (8kB) ldi zh,high($2000) gcls1: ldi r17,0 ;Speicherinhalt $00 rcall w_dat ;in LCD-Puffer schreiben ldi r17,$c0 ;Kommando Data-Write rcall w_cmd ;als Kommando senden sbiw zh:zl,1 ;Zähler runter brne gcls1 ;nochmal, bis alle Zellen fertig sind ret Dies müsste dir aber eigentlich beim Lesen meines Codes aufgefallen sein. ...
So verdreht können die Pins am Datenport nicht sein, es sei denn ich hätte den gesmapten Port verdreht. Mh das müsste ich mal überprüfen. Durch Das Testen mit LEDs habe ich herausgefunden, dass die Befehle Reset und Display ON schon einmal funzen. Aber Diese Initialisierung ruft nach dem Display on dieses Muster auf. Zwischendurch treten keine Zustände mer auf, die Linien verursachen. Danach habe ich das Beispiel von Seite 34 einfach angehängt. Wieder funzen die Befehle Display ON und Display off. Zwischendurch treten keine undefinierten Zustände auf. Als Ergebnis ist das Display aber in zwei hälften unterteilt. Die obere ist fast du 100% schwarz mit weißen 8x8Pixelflecken und die untere Hälfte ist fast zu 100% weiß mit schwarzen 8x8Pixelflecken. Grübel.... Ich untersuche die Verkabelung noch einmal...
lol Dann ist das mit dem Muster ja normal. Die Routine setzt nämlich nur die Zeiger und schreibt zwei Pixel. Die findet man ohnehin hie, wenn man den Rest mit Mist voll hat. Das war mal eine super Aussage und sie ist verdammt simpel. Ich lösche das Display jetzt einfach mal :-)
Wie schon von Hannes erwähnt mußt Du erst mal sehen, das Du das LCD richtig initialliesierst und dessen RAM löscht. So wie auch beim AVR bzw. µC nach Einschalten dessen RAM einen undefinierten Zustand (wirres Zeugs) hat, ist das beim LCD wohl auch der Fall. Also prüfe im Stromlosen Zustand mit nen Multimeter (Durchgangsprüfer) alle Leitungen. Wenn das passt (Versorgung, Daten- und Steuerleitungen) geht es an die Initiallisierung, also Reset des LCD und CGRAM löschen. Geht das, LCD ohne wirren Inhalt, dann Zeichenausgabe. Geht das, dann komplette Zeichenketten-Ausgabe. Geht das, dann Grafik. @Hannes: Hast Du noch so nen schönes Grafik-LCD übrig? Würde mich mal interessieren. MfG Andi
In diesem Initialisierungsbeispiel scheint echt kein Stück gelöscht zu werden. Ich frage mich nur, warum da kein Text erscheint, obwohl da ein Punkt addressiert wird....
Du hast die Initialisierung abgetippt... Vielleicht hättest du versuchen sollen, sie zu verstehen. Denn sie ist etwas abstrahiert. Man muss nämlich zwischendurch auch den Status lesen und warten, bis das LCD wieder bereit ist. Konstanten... Ich benutze das Format, was mir im Moment am geeignetsten erscheint. Das ist manchmal BIN (0b01111111), oft HEX ($7f) und manchmal dezimal. Oktal benutze ich aber nicht. Es kommt also immer auf die Situation an. Warum sollte ich einen Schleifenzähler denn in BIN oder HEX angeben, wenn ich in DEZ seinen Wert viel besser erkennen kann. Handelt es sich um Speicherbereiche, dann ist HEX oft übersichtlicher. Pull-Ups sollten während des Einlesen des Status-Bytes aktiviert sein. Das Statusbyte sollte vor jedem Schreibzugriff ausgewertet werden um zu erkennen, ob das LCD schon wieder bereit ist. Ansonsten übernimmt das LCD das gesendete Byte nicht und macht Blödsinn. Das Beispiel von Seite 34 setzt Attributes zu einem Text, den du nicht im LCD hast. Es ist also Nonsens. ...
@Andi: Nööö... So viele waren es nun auch wieder nicht. Da kann ich keins von abgeben. Tut mit leid... Was machen die Lüfter? - Klappt das nun? ...
Danke der Nachfrage und auch Deiner Opfervollen Zeit! Ich sende Dir noch die Schaltung wie ich sie momentan habe und auch mit einer Mindeststromversorgung. Habe das erst mal beiseite gelegt und konzentriere mich gerade noch auf einen (ziemlich) genauen RTC mit 100KHz an TOSC1 des µC. Zwischenergebnis eines Software-Abgleiches für den etwas zu langsammen Quarz kannst Du in nen anderen Thread lesen. Sinn des ganzen ist auch dass das Board ohne Haupt-Betriebsspannung wegen der internen Uhr weiterlaufen soll und da ist das mit dem Timer2 für den Power-Save genau richtig. Natürlich dann ohne Regelung, PWM und LCD. Eine entsprechende Pufferung mit Batterie oder Kondensator/en muß dann noch her wo ich deswegen hier wieder rumlöchern werde. MfG Andi
Also das mit dem Abfragen geht in meinem Fall eigentlich gar nicht, da ich das Display an ein Shiftregister hängen wollte. Diese Direktansteuerung mache ich im Moment nur, damit ich einen Fehler ausschließen kann. Ich nehme an, dass 2sek zwischen den Befehlen eindeutig ausrechen g Später möchte ich das natürlich optimieren.. So unberechenbar kann das doch nicht sein, oder etwa doch?
Also ich habe bei diesem Initialisierungsbeispiel einfach die Texthomearea aus dem Displayspeicher herausgeschoben und dann habe ich die Number of Graphicarea auf den gesampten Bildschirmbereich ausgedehnt. Der Effekt ist sehr irretierend! Ersteinmal erweckt der Speicher auf den ersten Blick den Eindruck, als währe er Linear ansprechbar anstatt, dass er in Blöcke unterteilt ist, weil die zweiten 8 Punkte rechts neben den ersten erscheinen und nicht darunter und zweitens ist jetzt auf einem Mal links eine Reihe von "e"s, die sich von oben bis unten hindurchzieht. 16mal, genau wie es auch sein sollte, wenn ich 16es gemalt hätte. Habe ich aber nicht. Diese Wiederholung wäre ja ganz ok. Weiterhin irritierend ist, dass die anzeige rechts neben diesen zwei reihen wieder zufällig ist. Oder wenigstens sind das nicht die Zeichen, welche ich eingegeben habe, sondern Buchstaben usw.
Und warum hast du das gemacht?? Welcher Sinn steckt hinter dieser Handlung? ...
Ich glaube ich habe den Fehler gefunden. Dazu: Wenn ich zwei Bytes hereinschiebe, welches ist das Lowbyte, wo Bit 0 enthalten ist und welches Byte ist das, welches Bit 16 enthält?? Das erste enthält Bit16, oder? Ich glaube ich habe den Fehler irgendwie dadurch verursacht, dass ich einen Pointer ausversehen nicht verändert habe und dieser Zeigt dan in den Textbereich.... http://www.freak5mynew.no-ip.info/Muell/DisplayAusgabeZeichen.jpg (Ich habe den Kontrast erhöht, da man sonst die Zeichen auf dem Foto kaum sehen konnte.)
Zum Warum: Also ich wollte mehr als einen Pixel setzen. Außerdem wollte ich testen ob die Addressierung so geht, wie ich es dachte nämlich in 8x8 Pixelblöcken
Jetzt lies Dir erst mal in aller Ruhe 10 mal das Datenblatt durch. Ein Grafikspeicher wird meistens linear angesprochen. Das war so damals bei den Homecomputern (ZX-Spectrum, C64, AtariST, Amiga500) und ist heute bei den modernen VGA-Karten. Also warum auch nicht bei solch relativ kleineren LCD´s. Also, bei 128 Pixel in der ersten Zeile hast Du 16 Bytes für die erste Zeile, Adresse geht von 0 bis 15. In der zweiten Zeile ebenfalls und die Adresse ist dann von 16 bis 31 usw. Das Adress-Mapping steht übrigens ab Seite 11 im Datenblatt. Die Klötzchengrafik kommt wohl daher, das der Textspeicher ab Adresse 1000h (0x1000) mit nicht gelöscht war (sinnloses Zeugs nach Einschalten) und der LCD-Controller das eben einfach am LCD angezeigt hat. MfG Andi
Aber wenn man die erste Zeile in 16 Einheiten unterteilt ist das doch nicht mehr Linear. ich dachte man setzt den Zeiger auf einheit 1 und schreibt diese ganz voll. Aber als ich die zweiten 8Bit geschrieben habe sind die als erstes in die Einheit 2 gekommen. Ich dachte ebend, dass man dann dieses 8x8Kästchen erst zuende schreibt, dann den Zeiger erhöht und dann das nächste nimmt. So wie es jetzt passiert ist hat er anscheinend den Zeiger von selber erhöht. Naja ich habe jetzt ja schon eine Rückmeldung, was alles einfacher macht... jetzt bastele ich mir mal selber einen Code nach dem Datenblatt zusammen. Wenn das funtzt code ich etwas wie hannes, was die Ansteuerung erleichtert.
Ach mönsch! In einem Byte hast Du 8 Bit. Das entspricht auch 8 Pixel auf dem LCD. Somit haben die ersten 8 Pixel links oben die BYTE-Adresse 0 mit Bit-Nr. 7 - 0. Die nächsten 8 Pixel haben BYTE-Adresse 1 mit Bit 7 - 0. Das Höchstwertige Bit (MSB) ist immer das linke. Um nun einen Pixel zu setzen mußt Du später, wenn Du soweit bist, mittels X- und Y-Koordinate die Byte- und Bit-Adresse berechnen. Beispiel: X = 51 (Horizontal von links nach rechts) Y = 75 (Vertikal von oben nach unten) B = 16 (Datenbytes je Zeile) Adresse = Y * B + X / 8 Bitnummer = X AND 7 also Adresse = 75 * 16 + 51 / 8 = 1206 Bitnummer = 51 AND 7 = 3 Aus der Bitnummer muß nun das Datenbyte zur Ausgabe "generiert" werden. Entweder man setzt Carry und schiebt das Carry-Bit in einer Schleife mit der Länge der Bitnummer nach rechts oder man bedient sich einer Tabelle in der Form: .db 0b10000000 .db 0b01000000 .db 0b00100000 .db 0b00010000 .db 0b00001000 .db 0b00000100 .db 0b00000010 .db 0b00000001 Sollen die anderen Pixel in einem Display-Byte nicht verändert werden muß man vorher das Display-Byte einlesen und mit dem neuen Datenbyte OR-Verknüpfen und dann zusammen ausgeben. MfG Andi
@Andi: Ich habe mir das viel vie komplizierter vorgestellt! Ich dachte, dass man einen Block jetzt auch nach unten hin vollschreiben muss, da man ja 8x8 Fonts hat. Jetzt ist das ja genauso wie auch beim PC. Damit man die anderen Punkte nicht beeinflusst könnte man ja auch 16KB Ram freihalten, wobei das irgendwie doch nicht so gut ist..... Ich denke, ich komprimiere das einfach vorher ordentlich :-) Das eigentlich verbleibene was wichtig ist: Aber wenn ich jetzt eine Adresse mit 16Bit setze, dann muss ich ja zwei Byte übertragen. Welches enthlält Bit 15 und welches Bit 0? Das erste ist doch das, welches Bit 8-15 enthält, oder?
Welches Byte zuerst gesendet werden muss, steht auf Seite 15 des Datenblattes (linkes Flowchart), das habe ich dir aber weiter oben schon geschrieben. Vielleicht solltest du es wirklich mal mit Lesen statt mit Fragen versuchen. ...
Ja, aber ist das auch generell so? Den Teil habe ich scon gesehen. Das Display funzt jetzt übrigens. Nur wenn ich den gesampten Bildschirm vollschreibe scheinen noch einige Fehler zu kommen, wenn ich ein bestimmtes Muster haben möchte. Ganz schwarz und ganz weiß geht auch schon. Eigenltich ist schon alles geklärt nachdem du mir gesagt hast, dass ich den Speicher löschen muss. Daran habe ich vorher noch nicht gedacht und das scheint auch das einzigste Problem gewesen zu sein! Gelesen habe ich das auch schon öfter, aber das letzte Mal ist schon etwas her... Danke aber für die ganze Mühe, die du dir Gemacht hast. Im Datenblatt steht das auch noch drin, aber ich habe das in meiner Hetze vorher immer überflogen ...
Jetzt ist mir aber doch noch ein Fehler aufgefallen! Ich habe zwei Schleifen. Die erste funktioniert und zeichnet den oberen Teil des Displays voll. Die zweite funktioniert nicht und zeichnet anstatt 00000000 irgendeinen Zufallswert. Woran liegt das? LDI r19, 64 Vollschreiben: LDI r20, 8 Vollschr: LDI r16, 0b11111111 rcall DataWrite LDI r16, 0b11000000 rcall CommandWrite LDI r16, 0b00000000 rcall DataWrite LDI r16, 0b11000000 rcall CommandWrite dec r20 BRNE Vollschr dec r19 BRNE Vollschreiben LDI r19, 64 Vollschreiben1: LDI r20, 8 Vollschr1: LDI r16, 0b00000000 rcall DataWrite LDI r16, 0b11000000 rcall CommandWrite LDI r16, 0b11111111 rcall DataWrite LDI r16, 0b11000000 rcall CommandWrite dec r20 BRNE Vollschr1 dec r19 BRNE Vollschreiben1
Beim Umkehren der Schleifen passiert das gleiche. Bedeutet das, dass die Timings zu niedrig sind? Solche unverhofften Zufallswerte meine ich aber öfter festgestellt zu haben. P.S.: Nebenbei ein lustiger effekt tritt auf, wenn man den AVR herauszieht. Das Muster wird dann doppelt so oft nur geschrumpft angezeigt.
Warum tritt der Fehler aber nur in der unteren Hälfte des Displays auf, unabhängig welche Schleife diese Hälfte beschreibt? Und warum tritt der Fehler nur bei dem Code auf? Vollständig schwarz oder weiß kann ich den Bildschirm auch ohne Fehler werden lassen. Gestreift habe ich bis jetzt nur mit niedrigen Timings probiert...
Vorheriges komplettes Löschen bringt auch nichts. Richtig eigenartig finde ich, dass ein durchgehendes Schreifenmuster keine Fehler hervorruft... Wie kann das sein? Wenn ich beim Wechsel des Musters irgendein Timing verfehlen sollte, so könnte der Fehler in der nächsten Zeile doch nicht noch einmal passieren. Außerdem sind die Spalten in meinem Muster immer mit dem gleichen "Müll" gefüllt.
Hallo, kleiner Einwurf von mir; ich habe ein Display, das selbstätig die Speicheradresse hochzählt. Somit hatte ich am Anfang auch ein Problem, weil ich das nicht erkannt hatte. Vielleicht hilft's Dir? Stephan.
Das nennt sich "Auto-Inkrement". Kann man beim Init ein- oder ausschalten. Steht alles im Datenblatt. Alos gründlich LESEN! MfG Andi
Ja ich habe es eingaschaltet. Die schwarzen Flächen werden ja auch korrekt gezeichnet. Die weißen eigentlich auch, nur wenn ich das Muster wechsele, dann ist das nicht mehr so. Das kann ich mir nicht erklären, weil es dem Display eigentlich egal sein müsste, was da steht.....
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.