Hallo Forum, ich habe mir bei Pollin dieses LCD 16x2 besorgt: LCD-Modul POWERTIP PC1602LRM-LSO-C (Best.Nr 120508) Ich habe das LCD mit Hilfe des Datenblattes angeschlossen und in BASCOM foldenden Code eingegeben: $regfile = "m8def.dat" $crystal = 3686400 Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4 Config Lcdbus = 4 Cls Locate 1 , 1 Lcd "test" Pins 5,7,8,9,10 sind auf GND gelegt. Zum Einstellen des Kontrast verwende ich ein 10k Poti. Aber das kann ich stellen wie ich will, es erfolgt keine Ausgabe (dunkel). Das einzige was funzt ist das backlight. Ich habe schon das Forum durchsucht, aber keinen passenden Hinweis gefunden. Ist denn der Code OK?
Hallo, Das Display braucht ne negative Kontrastspannung. Ich habe mir mit nem ICL7660 -5V erzeugen lassen und das Kontrastpoti zwischen VCC und -5V gehängt. Gruß Thorsten
Hallo Thorsten, danke für Deine Antwort. Das mit -5V ist im Datenblatt nicht ersichtlich (Pin3 Vo Contrast Adjust) :-( Also ich werde mir den ICL7660 erst besorgen müssen und probier es dann nochmal.
Thorsten Fritzke wrote: > Hallo, > > Das Display braucht ne negative Kontrastspannung. > Ich habe mir mit nem ICL7660 -5V erzeugen lassen und das Kontrastpoti > zwischen VCC und -5V gehängt. Warum nimmst Du nicht GND und -5V ? So wie Du das machst, funktioniert es zwar auch, verbraucht aber unnötig viel Strom. Grüße Björn
Für den ersten Test kannst du auch einfach ne Batterie dranhängen, wenn du nicht erst auf die Teile warten willst. Es fließt ja nicht besonders viel Strom...
@Björn Hast natürlich recht, dass weniger Strom fliessen würde, wenn das Poti zwischen GND und -5V hängt. Ich habe bei meinem Steckbrettaufbau nicht lange drüber nachgedacht und den GND Pin vom Poti auf die -5V gehängt. Funktionierte -> bin zufrieden. Gruß
Hallo, habe zu hause noch ein anderes LCD, von Reichelt (161F BL), und dieses angesteckt. Funzt leider auch nicht. :-( Hier mein Code: $regfile = "m8def.dat" $crystal = 3686400 Config Lcd = 16 * 1 Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4 Config Lcdbus = 4 Display On Cls Do Locate 1 , 1 Lcd "test" Waitms 100 Loop Habe nun mein Display sauber auf einem bread board verdrahtet und dieses mit meinem ATMega8 board verbunden. Also Anschlüsse sind korrekt. Wenn ich am Poti den Kontrast einstelle, so sehe ich eine Veränderung nur an den ersten acht Stellen. Die Stellen 9-16 verändern ihren Kontrast nicht. Was mache ich nur falsch?
Hallo, ich möchte euch nochmal um Hilfe bitten. Ich bringe dieses LCD (161F BL) nicht zum Laufen. Ich hab jetzt noch den externen Quarz abgeklemmt und zuvor die Fuse bits wieder auf den Ausgangzustand gestellt. Dann hab ich alle Anschlüsse mal auf den Port B angeklemmt. Ich hab schon sämtliche Tips hier im Forum probiert -ohne Erfolg. Was kann ich denn noch falsch gemacht haben?
Axel Hüser wrote: > Wenn ich am Poti den Kontrast einstelle, so sehe ich eine Veränderung > nur an den ersten acht Stellen. Das ist korrekt. Das 1x16-LCD ist in 2 Zeilen zu 8 Zeichen organisiert. > Die Stellen 9-16 verändern ihren > Kontrast nicht. Was mache ich nur falsch? Die meisten Text-LCDs stellen die Hälfte ihrer Pixel aktiv dar, solange das LCD noch nicht richtig initialisiert ist. Das kann man gut nutzen, um den Kontrast richtig einzustellen. Er ist richtig, wenn aktive und inaktive Pixel gut zu unterscheiden sind. Bei der "Inbetriebnahme" versorgt man also erstmal das LCD mit Betriebsspannung und stellt den Kontrast so ein, dass die Hälfte der Pixel aktiv ist, die andere Hälfte nicht. Nachdem der Kontrast richtig eingestellt ist, kann man die Software in Betrieb nehmen. Hier geht es erstmal nur um die Initialisierung. Die zur Initialisierung erforderliche Sequenz (Befehle und erforderliche Pausen) findest Du im Datenblatt des jeweiligen LCDs. Das erste Zeichen, dass die Initialisierung erfolgreich gewesen sein könnte, ist das Verschwinden der aktivierten Pixel. Gewissheit verschafft dann ein Schreibtest. Zu Deinem Programmbeispiel kann ich nichts sagen, da daraus nicht hervorgeht, welche Befehle in welchem Zeitabstand an das LCD gesendet werden. Ich bin es gewohnt, die Initialisierung gemäß Datenblatt (in Assembler) selbst zu schreiben, da kann ich wenigstens nachvollziehen, was wirklich passiert. Übrigens sind Text-LCDs recht unterschiedlich schnell, es ist also völlig normal, dass man das Timing an das LCD anpassen muss. ...
Hallo hannes, nachdem beim Datenblatt von Reichet nur eine Bemaßnug enthalten ist habe ich ich nach einem Datenblatt des Herstellers gesucht - und eines gefunden. Auf diesem ist nun auch die Pinbelegung anders (siehe Anhang). Jetzt weis ich leider nicht , wie man das LCD mit den Ports verbindet. Beginnt man mit Datenleitung0 oder Datenleitung1, oder einer anderen. Müssen die Leitungen dann auf PORTB0 bis PORTB3 gelegt werden? Müssen die nicht verwendeten Leitungen auf GND oder nicht? Es wäre sehr nett, wenn mir jeamd helfen würde!
Hi an deiner Stelle würde ich mehr dem Datenblatt vertrauen. Die Belegung dort entspricht dem Standartsnschluss für Text-LCDs. MfG Spess
Axel Hüser wrote: > Auf diesem ist nun auch die Pinbelegung anders (siehe Anhang). Was ist da anders? Das ist die übliche Pinbelegung. > Jetzt weis ich leider nicht , wie man das LCD mit den Ports verbindet. Das hängt von der Konfiguration der Software und den verfügbaren AVR-Ports ab. Es bringt z.B. nix, das LCD beim Tiny2313 mit PortC verbinden zu wollen. > Beginnt man mit Datenleitung0 oder Datenleitung1, oder einer anderen. Bei diesen Defiziten solltest Du Dir vielleicht mal das AVR-Tutorial auf dieser Webseite hier ansehen. Es ist zwar für Assembler, sollte Dir aber das allgemeine Hardware-Wissen vermitteln können. > Müssen die Leitungen dann auf PORTB0 bis PORTB3 gelegt werden? Müssen > die nicht verwendeten Leitungen auf GND oder nicht? Die meisten LCDs haben PullUp-Widerstände für ihre Datenleitungen, was Du durch messen der Pegel in Erfahrung bringen könntest. Diese Leitungen lässt man dann offen. Es soll aber auch LCDs geben, die keine PullUps haben, dann legt man die Leitungen (sicherheitshalber über Widerstände) auf GND oder Vcc. > > Es wäre sehr nett, wenn mir jeamd helfen würde! Das scheint in Deinem Fall sehr schwierig zu sein, wir sprechen unterschiedliche Sprachen... Ich habe es gerne konkret und nachvollziehbar und programmiere AVRs daher sehr hardwarenah in Assembler. Du möchtest es Dir leicht machen und benutzt den Baukasten BASCOM. Als Nebenwirkung verschleiert Dir Deine Programmierumgebung, was wirklich passiert, da sie Dich auf Abstand zur realen Hardware hält und Dich zum Rätselraten animiert. Müsste ich ein unbekanntes Text-LCD anschließen, dann würde ich so vorgehen: - GND-Anschluss ermitteln (ist meist 'ne dicke Masseleiterbahn rund um die Platine) - Vcc-Anschluss ermitteln (hat meist Elko und Abblock-Cs gegen GND). - Betriebsspannung anlegen, Spannungsteiler für Kontrast erstmal auf 0V. - Kontrast vorsichtig verändern, bis die Hälfte der Pixel gut zu sehen ist, nun weiß ich, ob die Kontrastspannung negativ oder positiv sein muss und kann die Schaltung dementsprechend planen. Ich hatte schon LCDs von -12V bis +12V (gegen GND) Kontrastspannung. - Am AVR ein freies Nibble suchen, an das ich D4 bis D7 anschließe. - Am AVR zwei freie Portpins suchen, an die ich RS und E anschließe. - R/W auf GND legen, da ich nur schreiben will. - Einer Kopie meines Muster-LCD-Treibers (selbst geschriebene ASM-Routinen) per .equ-Direktiven mitteilen, an welchen Portpins das LCD angeschlossen ist. - Kurzes Testprogramm schreiben (Init, LCD-Init, Textausgabe, Endlosschleife) und LCD testen, falls es nicht will, die Timing- Parameter der LCD-Initialisierung und des Schreibens auf LCD entsprechend ändern, bis alles stabil läuft. - Kopie des modifizierten Treibers (Include-Datei) zur späteren Verwendung sichern. - Programm fertigschreiben. ...
Versuche es mal damit: $regfile = "m8def.dat" $crystal = 3686400 Config Lcd = 16 * 1 Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4 Config Lcdbus = 4 Initlcd Cls Do Locate 1 , 1 Lcd "test" Waitms 100 Loop Das Display ist vorher nicht initialisiert worden, da der Befehl "Initlcd" fehlte. MfG Paul
> Das Display ist vorher nicht initialisiert worden, da der Befehl > "Initlcd" > fehlte. Tja, sowas fällt natürlich nur dem eingefleischten BASCOM-Profi auf... ;-) Gruß in die Mitte Deutschlands... Hannes
Ach Hannes, lange nicht mehr "gesehen". ;-) Ja, das ist immer so eine Sache, die man schnell mal übersieht, denn das Programm läuft ja trotzdem, nur gibt es nichts aus. Ich habe aber auch schon Displays gehabt, die selbst mit 128Khz getaktet waren und dann haut der Standardbefehl nicht mehr hin. Da habe ich nur zum Initialisieren ein Stück Assemblerprogramm hineinsetzen müssen. Aber das geht auch ganz gut mit: $Asm ..... $ End Asm Gruß in die Börde Paul
Hab nur geguckt, ob Paul wieder was gereimtes hinterlassen hat... leider diesmal nicht.
Uhu, Du mußt versteh'n, das kann nicht immer geh'n. Manches erfordert klaren Text, wie Bascom zwischen FOR und NEXT. duck und weg Paul
Paul Baumann wrote: > das geht auch ganz gut mit: > $Asm > ..... > > $ End Asm Das brauchst Du doch gar nicht. Wenn ich Roland Walter sein Online-Buch richtig verstanden habe, interpretiert BASCOM alles, was nicht BASCOM-Syntax ist, erstmal als Assembler. Man kann also die ASM-Befehle ohne Vorwarnung (Anmeldung) unter die BASCOM-Anweisungen mischen. Achja, gut gereimt (oder gedichtet?)... ;-) Bit- & Bytebruch, Hannes
Hallo an alle, ich habe meine Schaltung nochmal neu aufgebaut und mit dem Code von Paul getestet und - es funzt. Manchmal möchte man als Einsteiger aufgeben, wenn man nicht mehr weiter kommt. Aber nach einem Erfolgserlebnis geht's mit grösserem Eifer wieder weiter. Ganz besonderen Dank an Paul und Hannes. Werde mich nun mal mit dem Tutorial befassen.
Na siehste! ;-) Das ist das Gute an solchen Sachen: Den gemachten Fehler merkt man sich und beim nächsten Programm kann man dann neue einbauen. :-)) MfG Paul
Hallo, ich bin's nochmal. Hab jetzt festgestellt, dass nur die ersten 8 Zeichen angezeigt werden (LCD 1x16). Bei längerem Text werden Zeichen abgeschnitten. Muß ich da bei Config Lcd etwas verändern? Wenn ich eingebe Config Lcd=16*1a wird der Text zweimal angezeigt.
Axel Hüser wrote: > Hallo, > > ich bin's nochmal. Hab jetzt festgestellt, dass nur die ersten 8 Zeichen > angezeigt werden (LCD 1x16). Bei längerem Text werden Zeichen > abgeschnitten. Das ist korrekt. Die Erklärung hatte ich Dir bereits genannt: Beitrag "Re: Pollin LCD1602 keine Anzeige" Im Datenblatt des LCDs wirst Du den DD-RAM-Adressbereich für die zweiten 8 Zeichen finden. > > Muß ich da bei Config Lcd etwas verändern? Wenn ich eingebe Config > Lcd=16*1a wird der Text zweimal angezeigt. Tja, die genialen Config-Anweisungen von BASCOM... Da ist wohl wieder unser Paul gefragt... ;-) Vielleicht musst Du aber nur den Cursor (die LCD-Ausgabeposition, LCD-Kommando "Set DD-RAM-Adress") korrekt setzen... Bit- & Bytebruch... ...
Hannes Lux wrote: > Vielleicht musst Du aber nur den Cursor (die LCD-Ausgabeposition, > LCD-Kommando "Set DD-RAM-Adress") korrekt setzen... Jetzt überforder ihn doch nicht ;) Das HD44780 Datenblatt hat er sich sicher noch nicht angeschaut.
Simon Küppers wrote: > Hannes Lux wrote: >> Vielleicht musst Du aber nur den Cursor (die LCD-Ausgabeposition, >> LCD-Kommando "Set DD-RAM-Adress") korrekt setzen... > > Jetzt überforder ihn doch nicht ;) Das HD44780 Datenblatt hat er sich > sicher noch nicht angeschaut. Das ist sein gutes Recht. Denn ich habe mir die Doku zum JTAG-ICE MK II auch nicht angeschaut... ;-) Wobei es da einen kleinen Unterschied gibt: Ich habe mit dem MK II nix vor und muss daher auch nicht Bescheid wissen. ;-) ...
Hallo, also ich kann ja die Profis und Fortgeschrittenen unter euch verstehen, wenn sie von Anfängerfragen etwas genervt sind. Aber bitte versteht auch mal die andere Seite. Ich befasse mich seit wenigen Wochen mit uC und habe mich für Basic/Bascom entschieden, weil mir Basic schon etwas vetraut ist. (Im Forum habe ich für Asm, C und Basic jeweils Vor- und Nachteile gefunden). So, die Tutorials (Asm und C) hier im Forum haben mir da nicht viel geholfen. Da es mich selber nervt, wegen jeden Problems hier im Forum zu fragen, habe ich mir das AVR-Buch von Roland Walter zugelegt, um auch Grundlagen zu bekommen. Leider ist da über LCD's nichts enthalten. Lange Rede kurzer Sinn, ich würde mich freuen wenn mir jemand einen Lösungsweg gibt, es muss nicht die Lösung auf dem Silbertablett sein. Axel
Axel, du kämpfst an mehreren Fronten Was CONFIG LCD von BASCOM intern macht, ist für den User eine Blackbox. Blackboxen mögen viele nicht, vielleicht ein Grund für die Häme hier. BASCOM funktioniert für viele LCDs direkt aus der Kiste, für andere funktioniert es nicht. Bei genügend Druck seitens der User wird vom BASCOM-Hersteller ein weiterer Fummelparameter (CHIPSET=..., 16*1a...) in die Sprache eingeführt und ein paar mehr Displays funktionieren. Leider habe ich noch keine Datenbank gesehen, in der steht, welches Display mit BASCOM garantiert funktioniert, wenn man es so und so betreibt. Dieses Wissen sammeln und das wäre wahrscheinlich der bestbesuchte Wiki-Artikel oder das Verkaufsargument für Displays ;-) Du kannst eigentlich nur mit den Parametern vom CONFIG LCD rumfummeln und hoffen, eine praktikable Lösung herauszufinden. Wenn kein Parameter passt, tja... ...anderes LCD holen mit dem es bekanntermassen geht oder ...die komplette Ansteuerung selbst machen, d.h. auf die unbequeme Tour (Datenblatt lesen, Portleitungen klappern, Timing einhalten) so wie die Assembler-Leute oder die C-Leute (OK, die haben Libraries, die aber auch nicht immer passen). Tja und da wollen dich Hannes & Co, hinlocken ;-)
> habe mich für > Basic/Bascom entschieden, weil mir Basic schon etwas vetraut ist. Ich habe mich gegen BASCOM entschieden, weil mir BASIC (in mehreren Dialekten auf mehreren Systemen) sehr vertraut ist und ich daher sehr schnell festgestellt habe, dass mir BASCOM (aufgrund seiner hardwarefernen Blackbox-Baukastenstruktur) mehr Probleme schafft, als es lösen kann. > Tja und da wollen dich Hannes & Co, hinlocken ;-) Das kann (und will) ich nicht bestreiten. ;-) Ich bin nunmal davon überzeugt, dass man mit etwas Detailwissen direkt an der Hardware (also unter direkter Nutzung der Hardware-Gegebenheiten) mehr erreichen kann und ggf. sogar besser zum Ziel kommt, als unter Benutzung eines Software-Baukastens, der nur eine beschränkte Bibliothek zur Verfügung stellt, mir aber wichtige Informationen vorenthält. Und dafür soll ich auch noch zahlen, während ich das AVR-Studio (also Assembler) durch den Kauf der AVRs sowiso mitfinanziere... ...
Versuche mal, das Display mit "Config LCD = 16*2" zu initialisieren. Es kann sein, daß Dein Display so aufgebaut ist, daß praktisch 2 Stück 8*1 Displays dort drin nacheinander angeordnet sind, so daß das Ding zweizeilig initialisiert werden muß. Da 8*1 standardmäßig nicht vorgesehen ist, guck mal, ob es so geht. Wenn nicht, mußt Du in den sauren Apfel beißen und Dir aus dem Datenblatt die Initialisierungs-Sequenz raussuchen und ein eigenes "Initlcd" in Assembler dafür schreiben. MfG Paul
Hallo an alle, danke nochmal für euere verständlichen Antworten. Mit dem LCD hab ich das jetz so gelöst: Do Locate 1,1 LCD "TextEins" Locate 2,1 LCD "TextZwei" Waitms 50 Loop Auf dem LCD erscheint dann 'TextEinsTextZwei' (Alle anderen Versuche mit 16*1,16*1a, 16*2 brachten keinen Erfolg) Also so wie ich das sehe wird es doch besser sein, mich in Assembler einzuarbeiten. Sieht für einen Anfänger nur ziemlich schwierig aus. Aber was hilft's. Besser jetzt als nie. Axel
Hallo an alle, ich nun den Tipp von einigen von Euch (Hannes und stefb) beherzigt und mich in der vergangenen Woche an Assembler herangewagt. Ich habe dazu mit dem Tutorial gearbeitet. Ich bin nun bis zu den LCD-Routines vorgestoßen und habe versucht mein LCD zur Anzeige zu bringen. Aber es tut's leider nicht. (Alle Pixel des LCD sind hell; es sollte aber 'T' angezeigt werden. Programmiert habe ich mit AVR-Studio 4 geflashed mit Ponyprog ATMEGA8, intern 1 MHz (Hardware ist OK; Wenn ich eine Hex-Datei, mit Bascom programmiert, flashe, wird mein Text angezeigt.) Und hier mein Code: .include "m8def.inc" .def temp1 = r16 .def temp2 = r17 .def temp3 = r18 ldi temp1, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp1 ldi temp1, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp1 ldi temp1, 0xFF ; Port D als Ausgang out DDRD, temp1 rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen ldi temp1, 'T' ; 'T' anzeigen rcall lcd_data loop: rjmp loop .include "lcd-routines.asm" Kann mir jemand von Euch auf die Sprünge helfen?
Im LCD Code ist noch immer 1Mhz als Taktfrequenz eingetragen (XTAL) Wenn du da nicht den korrekten Wert einträgst, werden die Verzögerungsschleifen falsch (zu kurz) berechnet. Dadurch stimmt dann das Timing in der heiklen Initialisierungsphase nicht mehr.
Hi! Das schaut auf den ersten Blick nicht schlecht aus, aber In Bascom: >Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , >Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4 In ASM >.equ PIN_E = 6 >.equ PIN_RW = 5 >.equ PIN_RS = 4 Wo haste denn jetzt Pin_E ? Viel erfolg, Uwe
Hi Uwe, ich glaub, ich weis, was du meinst. E, RW und RS habe ich nicht richtig einem Pin zugeordnet .equ PIN_E = 6 (E = Portd.5) .equ PIN_RW = 5 (GND) .equ PIN_RS = 4 (Rs = Portd.4) Da muss ich erstmal nachlesen, was ich an Stelle von 4, 5 und 6 schreiben muss.
Du schreibst am Anfang: .def temp1 = r16 usw..., jedoch taucht die gleiche Definition in den LCD-Routines mit anderen Registern nochmal auf. Ach ja, schreibe am Ende unter das .include lcd-routines.asm noch ein NOP oder RET. Bei mir hat das AVR-Studio ohne dies die Routinen nicht eingebunden, aber auch keinen Fehler gemeldet. Beim Powertip-LCD musste ich R/W auf Masse legen, damit es funzt. Thomas
Hi, Wenn es in Bascom geht dann sollte "Pin_RW" auf GND sein und bleibt deshalb in ASM ebenfalls unbeachtet. "Pin_E" müsste also auf Pin 5 zu finden sein, also: .equ PIN_E = 5 (E = Portd.5) .equ PIN_RS = 4 (Rs = Portd.4) Viel Erfolg, Uwe
Hallo, habe nun den Befehl 'ret' ganz am Ende eingesetzt und die Portzuweisung korrigiert: (RW war bereits auf Masse gelegt) .equ PIN_RW = 5 ; GND .equ PIN_E = PD5 ; PD5, pin 11 .equ PIN_RS = PD4 ; PD4, pin 6 und fogende Anweisung ergänzt: ldi ZL, LOW(text*2) ldi ZH, HIGH(text*2) rcall lcd_flash_string loop: rjmp loop text: .db "TestABCDEFGHIJKL",0 ; Mein String Ein erster Erfolg :-D Die ersten acht Zeichen (TestABCD) werden angezeigt. Für den Rest muß ich noch suchen (Display 8+8)
> Ein erster Erfolg :-D > Die ersten acht Zeichen (TestABCD) werden angezeigt. Für den Rest muß > ich noch suchen (Display 8+8) Die wirst Du dort (im DD-RAM) finden, wo bei zweizeiligen Displays Zeile 2 beginnt (Datenblatt fragen). ...
Axel Hüser wrote: > (RW war bereits auf Masse gelegt) > > > .equ PIN_RW = 5 ; GND > .equ PIN_E = PD5 ; PD5, pin 11 > .equ PIN_RS = PD4 ; PD4, pin 6 Das ist nicht sehr schlau. In deiner Definition benutzen jetzt RW und E denselben Pin. Dein Glück ist es, dass die Tutorial Routinen RW nicht benutzen. Würden sie das tun, dann würde sich die Ansteuerung von RW mit der Ansteuerung von E in die Haare kommen. Mal angenommen das wäre anders und die Routinen würden RW ansteuern: Dann würde das Programm versuchen auf dem Pin 5 mit der RW Leitung zu wackeln. Gleichzeitig würde besagte Routine aber auch versuchen auf dem Pin 5 mit der E Leitung zu wackeln. Und das kann so nicht gut gehen. Wie gesagt: Im konkreten Fall ist das kein Problem, weil die Funktionen RW gar nicht ansteuern. Aber für die Zukunft solltest du die Dinge auch mal aus Sicht deines Programms betrachten und nicht nur aus der Sicht wie du das Display angelötet hast.
Hi, >.equ PIN_RW = 5 ; GND >.equ PIN_E = PD5 ; PD5, pin 11 halte ich für recht gefährlich, weil PD5 ist PortD, Pin 5 also genauso wie Pin_RW = 5. Wenn du irgendwann RW benutzen solltest wird der selbe Pin angesprochen. - 2.Zeile: versuche mal mit ldi temp1 ,$c0 ;=ADR $40+$80 für ADR DDRam set rcall lcd_command ob du da die 2. Zeile erreichen kannst. Wenn ja, musst du nach 8 Zeichen die neue Adresse setzen und dann weiter ausgeben. Übrigens > in temp3, LCD_PORT > andi temp3, 0x80 > or temp1, temp3 Was hast du denn eigentlich an PD7 drann, das du es nicht verändern möchtest(0x80 ist die Wertigkeit von Bit7)? Wenn da nichts ist, einfach weglassen, "push/pop temp3" ebenfalls Viel Erfolg, Uwe
Hallo Uwe, langsam, langsam, dass ein Oldie auch noch mitkommt ;-) 1.Problem - falsche Portzuweisung: Also wenn ich RW dauerhaft auf GND lege (nicht am uC anschliesse), was muß ich dann zuweisen? .equ PIN_RW = ? oder kann ich diese Zeile weglassen und dann lcd_init: ... ... ori temp1, (1<<PIN_E) | (1<<PIN_RW) | (1<<PIN_RS) | 0x0F ... verändern?
Axel Hüser wrote: > Hallo Uwe, > > langsam, langsam, dass ein Oldie auch noch mitkommt ;-) > > 1.Problem - falsche Portzuweisung: > > Also wenn ich RW dauerhaft auf GND lege (nicht am uC anschliesse), was > muß ich dann zuweisen? Im Idealfall kommt dann RW in deinem Code gar nicht mehr vor! Du hast ihn ja nicht am µC angeschlossen, also sollte es im Code auch nicht auftauchen. Nun weis ich natürlich, dass du den Democode aus dem Tutorial genommen hast. Dort ist RW drinnen, eventuell in der Absicht das Tut mal dahingehend zu erweitern, dass RW auch wirklich angesteuert wird. Aber: Wie auch immer, solltest du dafür sorgen, dass in 1 Jahr keine Verwirrung aufkommt, wenn jemand deinen Code studiert. Der sieht im Code: "RW ist an Pin 5 angeschlossen. Aha. Pin E ist ebenfalls an Pin 5 angeschlossen. Oha! Das kann aber nicht funktionieren!" Wenn du RW nicht aus dem restlichen Code entfernen willst, dann gib ihm eine Pin Nummer, die nicht benutzt wird und schreib im Kommentar dazu, dass RW hardwaremaessig nicht angeschlossen ist. > > .equ PIN_RW = ? > > oder kann ich diese Zeile weglassen und dann > > lcd_init: > ... > ... > ori temp1, (1<<PIN_E) | (1<<PIN_RW) | (1<<PIN_RS) | 0x0F > ... > > > verändern? Ja, das könntest du zb. tun. Wie gesagt: Es geht darum, Verwirrungen in absehbarer Zeit zu vermeiden. Irgendwann weist du nämlich nicht mehr, ob du jetzt beim LCD den RW angeschlossen hast oder nicht. Und wie das Leben so spielt, sieht man dann gerne einfach im Code nach, ob RW irgendwo verwendet wird anstatt dass Messgerät herauszukramen und die Leitung zu verfolgen. Am allerbesten wäre es: RW komplett aus dem Code herausoperieren. Am zweitbesten: Einen Kommentar dazu, dass RW nicht benutzt wird.
Hallo an alle, habe jetzt meine Zuordnung so umgeschrieben: .equ PIN_RW = PD6 ; PD6 nc .equ PIN_E = PD5 ; PD5, pin 11 .equ PIN_RS = PD4 ; PD4, pin 6 Nun zum 2. Problem - die 2. Hälfte des Displays: Hier mein aktueller Code: ; sendet einen Befehl an das LCD lcd_command: ... mov temp2, temp1 ; temp1 nach temp2 kopieren swap temp1 ; nibbles vertauschen andi temp1, 0b00001111 in temp3, LCD_PORT andi temp3, 0x80 or temp1, temp3 out LCD_PORT, temp1 ; Daten an LCD ausgeben rcall lcd_enable ; Enable-Routine aufrufen andi temp2, 0b00001111 or temp2, temp3 out LCD_PORT, temp2 ; Daten an LCD ausgeben rcall lcd_enable ; Enable-Routine aufrufen rcall delay50us ; warten ... ret ; zurück zum Hauptprogramm Also im Datenblatt steht unter 'Zuornung DD-RAM Adressen...': 1x16(8+8) 1.Zeile $00-$07 (linke Hälfte) 1.Zeile $40-$47 (rechte Hälfte) Also müssten diese Adressen doch im obigen Code aufgeführt werden???
Hi! >1.Zeile $00-$07 (linke Hälfte) >1.Zeile $40-$47 (rechte Hälfte) >Also müssten diese Adressen doch im obigen Code aufgeführt werden??? Nein, du übergibst sie in temp1. Meine Vorahnung war also richtig ldi temp1 ,$c0 ;=ADR $40+$80 für ADR DDRam set rcall lcd_command Adresse $40 ist 2.Zeile Zeichen1(die 2-ten 8 Zeichen) Dazu das Bit für "ADR DDRam set" = Bit7 = $80-> $40+$80 = $C0 Also $C0 an "lcd_command:" übergeben und an der Stelle dann weitere Zeichen ausgeben. > in temp3, LCD_PORT > andi temp3, 0x80 > or temp1, temp3 Die Frage steht immernoch. Was ist an PD7 drann? Viel Erfolg, Uwe
Hallo Uwe, tut mir wirklich leid, ich check im Moment gar nichts mehr. Wahrscheinlich hab ich mir zu Beginn mit den LCD's doch zu viel zugemutet. Ich such auch schon seit Stunden im Forum nach einem Beispielcode oder -zeilen, ohne Erfolg. Also mir ist klar, dass zuerst die acht Zeichen augegeben werden, danach eine Adressänderung und nun die zweiten acht Zeichen. Aber an welcher Stelle ? In den lcd-routines oder im Hauptprogramm? -Sorry- (Wenn ich im Programm einen ultralangen String eingebe, dann werden alle Zeichen (16) angezeigt. Also liegts nur an der Adresse für die 2.Zeile) ...Achso PD7? Das LCD ist neben der Stromversorgung nur mit den 4 Datenleitungen, E und RS angeschlossen. Die restlichen Pins des uC sind nicht belegt. Danke für Eure Geduld
Hallo Uwe und alle, nach einem Tag Ruhe versuch ich's mal wieder mit meinem LCD. Ich hab da immer noch meine Probleme wirklich zu verstehen, was da der Reihenfolge nach abläuft (ablaufen soll). Die Routine lcd_flash_string ruft für jedes Zeichen meines Strings die Routine lcd_data auf, bis Register '0' (Ende des Strings). Die Routine lcd_data gibt die ersten 8 Zeichen an das LCD - 1.Zeile. Wenn ich bis jetzt richtig läge, müßte ich doch am Ende der lcd_data die Anweisungen ldi temp1 ,$c0 ; Adresse für die 2.Zeile setzen rcall lcd_command schreiben und alle Anweisungen innerhalb von lcd_data wiederholen - Ausgabe der 2.Zeile? Ist das so falsch? Ich bitte Euch nochmal um Hilfe. Vielen Dank
Ich gehe mal davon aus, dass Du jetzt immernoch das 1x16 (2x8) LCD meinst, von dem ja auch die Rede war (hoffentlich verwechsele ich jetzt nichts, es laufen ja mehrere LCD-Threads parallel). Der HD44780 (und seine Kompatiblen) unterstützt (intern) erstmal ein LCD mit 2 Zeilen und 40 Zeichen. Diese sind je nach LCD anders angeordnet. Das 1x16 ist meist als 2x40 organisiert, wobei von den 40 Zeichen nur 8 dargestellt werden und die zweite Zeile rechts neben der ersten (siehe angehängtes Datenblatt Seite 15). Um den ganzen DD-RAM (Bildschirmspeicher, 2 mal 40 Zeichen) nutzen zu können, gibt es die Möglichkeit, die (meist kleinere) Anzeigeeinheit wie ein Fenster (Lupe) über den DD-RAM zu scrollen (Shift Display, Datenblatt Seite 14). Der DD-RAM ist dadurch auch bei kleineren Displays nicht verloren. Ich persönlich nutze dieses Feature aber (bewusst) nicht. Bei der Ausgabe (besonders von Strings aus Flash oder SRAM/EEPROM, aber auch aus zu ASCII-Strings umgewandelten Zahlen) ist also immer darauf zu achten, dass die Anzeigeposition "nicht aus dem Fenster läuft". Das LCD hat nämlich keinen Zeilenumbruch. Das ist erst der Fall, wenn die Anzeigeeinheit des LCDs den gesamten Inhalt des DD-RAMs gleichzeitig darstellen kann, wie das 2x40 oder das 4x20. Wobei das 4x20 meist so organisiert ist, dass die erste DD-RAM-Zeile in den Zeilen 1 und 3 dargestellt wird, die zweite DD-RAM-Zeile in den Zeilen 2 und 4. Also wieder kein Fließtext... Ich helfe mir (bei neueren Projekten) mit einem Bildschirmspeicher im AVR, der für jede Anzeigeposition ein Byte hat, dazu noch einige Bytes für die Verwaltung. LCD_DATA schreibt nur noch in diesen Bildschirmspeicher und wird aufgrund der fehlenden Warterei auf das Display verdammt schnell. Zusätzlich gibt es einen Job der Mainloop, der über einen Timer (über Semaphore) synchronisiert wird (1 bis 10 ms), der reiherum den Inhalt des Bildschirmspeichers an das LCD ausgibt, dabei die Adressen des Bildschirmspeichers prüft und die Ausgabepositionen entwirrt. Dies ermöglicht sorgenfreien Umgang mit dem LCD. Es versteht dadurch Fließtext (wenn das Display voll ist, fängt es von vorn an), das Positionieren der Ausgabeposition erfolgt durch einfaches Manipulieren des Printpointers (der von LCD_DATA benutzt wird). Leider habe ich lange nichts mit kleinen LCDs gemacht, daher habe ich dafür keine (erprobte) Routinensammlung für kleine LCDs. Die gibt es zur Zeit nur für das 8x24 (Controller M50530) und das 4x40 (2x HDD44780). ...
Hi, Ich mache es mal kurz: ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ldi temp1 ,$c0 ;=ADR $40+$80 für ADR DDRam set rcall lcd_command rcall lcd_flash_string loop: rjmp loop text1: .db "TestABCD",0 text2: .db "EFGHIJKL",0 ; Mein String lcd_flash_string liest bis eine 0 kommt. Mit ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) könnte man die Adresse für den 2.Teil direkt anwählen(vor dem 2.rcall lcd_flash_string) Du kannst also noch weitere feste Texte anlegen und über die "Marken"(text2:) aufrufen. Wenn du erneut in "Zeile1" schreiben willst musst du nur die Schreibadresse neu setzen: ldi temp1 ,$80 ;=ADR $00+$80 für ADR DDRam set rcall lcd_command Viel Erfolg, Uwe
Hallo Uwe, meinst Du so? ldi temp1, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp1 ldi temp1, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp1 rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ;text1 ausgeben ldi temp1 , $c0 rcall lcd_command ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) rcall lcd_flash_string ;text 2 ausgeben loop: rjmp loop text1: .db "TESTABCD",0 ; String, durch '0' angeschlossen text2: .db "EFGHIJKL",0 ; String, durch '0' .... Axel :-(
Hi! Ja, so wäre die absolut richtige Schreibweise. In deinem Fall könnte die 2. Adresszuweisung entfallen, weil "lcd_flash_string" mit der richtigen Z-Adresse zurückkommt. Bei mehreren Texten geht nur deine Art. Übrigens: ldi ZL, LOW(text1*2+4) ldi ZH, HIGH(text1*2+4) ldi temp1,$84 ;Zeile1,Zeichen5 rcall lcd_command rcall lcd_flash_string ;text1 ausgeben ldi temp1 , $c0 rcall lcd_command ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) rcall lcd_flash_string ;text 2 ausgeben loop: rjmp loop text1: .db "TESTABCD",0 ; String, durch '0' angeschlossen text2: .db "EFGHIJKL",0 ; String, durch '0' sollte "____ABCDEFGHIJKL" auf dein Displ. schreiben. Ohne: ldi temp1,$84 ;Zeile1,Zeichen5 rcall lcd_command sollte "ABCD____EFGHIJKL" erzeugen. Viel Erfolg, Uwe
Hallo Uwe, bin schon langsam am verzweifeln :-( Wenn ich den Code verwende, den ich vorhin gepostet habe, gehen nur die ersten 8 Zeichen. Wenn ich deinen letzten Code eingebe, wird bei den ersten acht Stellen eine unterschiedliche Anzahl von Zeichen angezeigt. Mal 5, mal 6, mal 2 Zeichen. Und immer nur die Buchstaben aus Text2. Wenn ich neu flashe oder die Reset-Taste drücke, ist die Anzeige immer anders. Kann das vielleicht am ISP-Kabel liegen oder stimmt etwas mit den delays nicht?
Axel Hüser wrote: > Kann das vielleicht am ISP-Kabel liegen oder stimmt etwas mit den delays > nicht? Was für einen ISP-Programmer benutzt Du? Gibt der nach dem Flashen die Leitungen wieder frei (hochohmig)? Schau doch mal, was passiert, wenn Du das ISP-Kabel abziehst. Vielleicht ist auch einfach Deine Leitung zum LCD zu lang? ...
Hallo hannes, hier mal ein Foto von meinem Aufbau. Als ISP-Programmer nutze ich diesen hier: http://www.roboternetz.de/wissen/index.php/AVR-ISP_Programmierkabel. Wie weiter oben schon mal gesagt, wenn ich eine hex-Datei, von Bascom erzeugt, flashe, funktionierts einwandfrei. Deshalb habe ich angenommen, dass der Aufbau selbst OK ist. Axel
Hallo an alle, also der einzige Code, bei dem die Anzeige korrekt erscheint, ist: ldi temp1, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp1 ldi temp1, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp1 rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ldi temp1 , $c0 rcall lcd_command ;ldi ZL, LOW(text2*2) ;deaktiviert ;ldi ZH, HIGH(text2*2) ;deaktiviert ;rcall lcd_flash_string ;deaktiviert ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; loop: rjmp loop text1: .db "TESTABCD EFGHIJKL",0 ; String, durch '0' angeschlossen text2: ;.db "EFGHIJKL",0 ;deaktiviert Ich habe in text1 32 Lehrzeichen eingegeben und danach die 2.Hälfte des Strings. Es erscheint dann die Anzeige 'TESTABCDEFGHIJKL' mit blinkendem Cursor und Unterstrich (wie eingestellt). Nach jedem flashen oder Reset erscheint immer die gleiche Anzeige. Aber trotzdem sollte es auch ohne die 32 Leerzeichen gehen, oder? Axel
Axel Hüser wrote:
> Aber trotzdem sollte es auch ohne die 32 Leerzeichen gehen, oder?
Im Grunde schon.
Ich vermute mal, dass nach dem Neusetzen der Cursorposition
das nachfolgende Ausgeben das Textes zu schnell erfolgt.
(Jedes LCD braucht eine gewisse Zeit um ein Kommando zu
verarbeiten).
Mach doch mal hier eine kleine Verzögerung hinein (ein paar ms,
vielleicht so um die 10 ms, in der Init-Funktion werden doch
solche Warteschleifen verwendet).
ldi ZL, LOW(text1*2)
ldi ZH, HIGH(text1*2)
rcall lcd_flash_string ;text1 ausgeben
****** Hier etwas warten ****** <<<<<<<<--------
ldi temp1 , $c0
rcall lcd_command
****** Hier etwas warten ****** <<<<<<<<--------
ldi ZL, LOW(text2*2)
ldi ZH, HIGH(text2*2)
rcall lcd_flash_string ;text 2 ausgeben
loop:
rjmp loop
Hallo karlheinz, habe jetzt jeweils dreimal die Anweisung rcall delay5ms eingefügt, Anzeige ohne Veränderung. Axel
Hi! >1.Zeile $00-$07 (linke Hälfte) >1.Zeile $40-$47 (rechte Hälfte) >Ich habe in text1 32 Lehrzeichen eingegeben und danach die 2.Hälfte des >Strings. Es erscheint dann die Anzeige 'TESTABCDEFGHIJKL Das passt aber nicht ganz, 32 + 8 Zeichen sind 40(dezimal!)=$28 $40 = 64(dez) $28+$80=$A8 Dann versuche doch mal bitte: ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ;text1 ausgeben ldi temp1 , $A8 rcall lcd_command ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) rcall lcd_flash_string ;text 2 ausgeben loop: rjmp loop text1: .db "TESTABCD",0 ; String, durch '0' angeschlossen text2: .db "EFGHIJKL",0 ; String, durch '0' Das wäre trotzdem eine recht ungewöhnliche Adresse. Viel Erfolg, Uwe
Uwe wrote: > Hi! >>1.Zeile $00-$07 (linke Hälfte) >>1.Zeile $40-$47 (rechte Hälfte) > >>Ich habe in text1 32 Lehrzeichen eingegeben und danach die 2.Hälfte des >>Strings. Es erscheint dann die Anzeige 'TESTABCDEFGHIJKL > > Das passt aber nicht ganz, 32 + 8 Zeichen sind 40(dezimal!)=$28 > $40 = 64(dez) Der Controller hat aber keine zwei mal 64 Bytes DD-RAM sondern nur zwei mal 40 Bytes. Unter diesem Aspekt passt das schon. Auch wenn die Adressen einen Versatz von 64 Bytes haben. > $28+$80=$A8 > Dann versuche doch mal bitte: > ldi ZL, LOW(text1*2) > ldi ZH, HIGH(text1*2) > > rcall lcd_flash_string ;text1 ausgeben > > ldi temp1 , $A8 > rcall lcd_command > > ldi ZL, LOW(text2*2) > ldi ZH, HIGH(text2*2) > > rcall lcd_flash_string ;text 2 ausgeben > > loop: > rjmp loop > > text1: > .db "TESTABCD",0 ; String, durch '0' angeschlossen Und bitte die Strings nicht "ANschließen", dann können die ja nicht weg... ;-) Wobei die Anweisung ".db "TESTABCD",0" auch nicht korrekt ist und zumindest eine Warnung beim Assemblieren verursachen müsste, denn jede auf Flash angewendete .db-Anweisung muss eine gerade Anzahl von Bytes haben, was hier nicht der Fall ist. Der Assembler hängt also eine weitere Null an und gibt eine Warnung aus. > > text2: > .db "EFGHIJKL",0 ; String, durch '0' Auch diese .DB-Anweisung provoziert eine Warnung. > > Das wäre trotzdem eine recht ungewöhnliche Adresse. > > Viel Erfolg, Uwe ...
Mir ist gerade eingefallen, dass ich März einen Termostat für meinen Boiler mit LCD 16x2 gebaut hatte und dabei schon mit Bildschirmspeicher gearbeitet hatte. Es gibt also doch schon einen LCD-Treiber für 16x2, der die üblichen Nachteile kompensiert. Im Anhang sind die LCD-Routinen, das Hauptprogramm folgt, in dem man sehen kann, wie die Routinen eingebunden werden. ...
Hier das Hauptprogramm, es ist etwas verwurschtelt, da es Bau-Ruine ist und seine Arbeit tut, obwohl es nicht an allen Stellen optimal ist. ...
Hallo Uwe, Hannes, vielen, vielen Dank für Eure Mühe und Geduld ;-) Bin jetzt mal für eine Woche beruflich weg und würde mich danach nochmal im Forum melden. Axel
Die anderen Include-Dateien für die Ausgabeformatierung habe ich jetzt mal zu einer Textdatei zusammengefasst, um nicht noch 6 Beitäge posten zu müssen. ...
Hi, @Hannes Du meinst das Displ. hat eine Adresslücke die automatisch übersprungen wird? Wäre auf jedenfall eine Erklärung. Muss mal das pdf ansehen.....neenee Die Adressen sind dez. angegeben.(jedenfalls nicht in hex) Meine letzte Aussage(ldi temp1 , $A8) sollte also passen. >Wobei die Anweisung ".db "TESTABCD",0" auch nicht korrekt ist und >zumindest eine Warnung beim Assemblieren verursachen müsste Das stimmt, bis auf die 2 verlorenen Byte entsteht aber kein Schaden und für Axel ists übersichtlicher. Besser wäre natürlich: ldi ZL, LOW(text*2) ldi ZH, HIGH(text*2) : : ldi ZL, LOW(text*2+9) ldi ZH, HIGH(text*2+9) : : text: .db "TestABCD",0,"EFGHIJKL",0 Du musst zugeben, das ist etwas unübersichtlicher. Viel Erfolg, Uwe
Uwe wrote: > Hi, Low... ;-) > @Hannes Du meinst das Displ. hat eine Adresslücke die automatisch > übersprungen wird? Wäre auf jedenfall eine Erklärung. Ich weiß es nicht, halte es aber für möglich... > Muss mal das pdf ansehen.....neenee Die Adressen sind dez. > angegeben.(jedenfalls nicht in hex) Meine letzte Aussage(ldi temp1 , > $A8) sollte also passen. Die "Nullpunkte" beider LCD-Zeilen liegen 64 Bytes auseinander, bei gesetztem Bit7 (Kommando-Ident) sind das $80 und $C0. Mit $A8 kann ich nichts anfangen... > >>Wobei die Anweisung ".db "TESTABCD",0" auch nicht korrekt ist und >>zumindest eine Warnung beim Assemblieren verursachen müsste > Das stimmt, bis auf die 2 verlorenen Byte entsteht aber kein Schaden und > für Axel ists übersichtlicher. Besser wäre natürlich: > > ldi ZL, LOW(text*2) > ldi ZH, HIGH(text*2) > : > : > ldi ZL, LOW(text*2+9) > ldi ZH, HIGH(text*2+9) > : > : > > text: > .db "TestABCD",0,"EFGHIJKL",0 Nööö, einfach bei Bedarf die zweite Null selbst anhängen. Dann weiß man wenigstens, dass der erzeugte Binärcode mit dem Quelltext übereinstimmt und vermeidet nebenbei noch die Warnung: .db "TestABCD",0,0 .db "EFGHIJKL",0,0 Solange es nur um Text-Terminierung geht, ist das eigentlich schnuppe, trotzdem habe ich mir angewöhnt, Code so zu schreiben, dass weder Fehlermeldungen noch Warnungen entstehen. Wenn man sich erstmal (durch fehlende Disziplin) an Warnungen gewöhnt hat, dann übersieht man schnell mal wichtige Warnungen... 8-( > > Du musst zugeben, das ist etwas unübersichtlicher. Na so würde ich es ja auch nicht machen... ;-) > > Viel Erfolg, Uwe Wobei? (Erfolg), meine LCDs laufen... ;-) ...
Hi! @Hannes >trotzdem habe ich mir angewöhnt, Code so zu schreiben, dass weder >Fehlermeldungen noch Warnungen entstehen. Und wie machst du das wenn du zb.XL/XH mit einem neuen Namen austattest? Das erzeugt ja auch Warnungen.;-) Ich lese mir das jedenfalls durch und beurteile ob es wichtig ist. Ob du nun die 2 Nullen anhängst oder der Assembler ist doch egal. Wichtiger wäre mir im Bedarfsfall die 2 Byte noch zu haben. Ich habe mich heute erst mächtig über 26 Byte gefreut die ich freisetzen konnt. Das sind immerhin 13 Befehle. >Die "Nullpunkte" beider LCD-Zeilen liegen 64 Bytes auseinander Hoffentlich irrst du dich da nicht. Schaue dir doch das Datenblatt, welches Axel oben angehangen hat, mal richtig an. Ich vermisse jedenfalls ein 0x.. oder $ oder Hex in der Darstellung. Schönen Tag noch, Uwe
Uwe wrote: > Hi! > @Hannes Ach, Uwe, eigentlich habe ich für solche Spielchen gar keine Zeit... >>trotzdem habe ich mir angewöhnt, Code so zu schreiben, dass weder >>Fehlermeldungen noch Warnungen entstehen. > Und wie machst du das wenn du zb.XL/XH mit einem neuen Namen austattest? Warum sollte ich das tun? - Die haben doch Namen. Und wenn ich es doch mal tun müsste, würde ich mich daran erinnern, dass es entsprechende Directiven im Präprozessor des Assemblers gibt, würde in der Hilfe nachschaun und die entsprechenden Directiven verwenden (ich habe jetzt absolut keine Lust zum Nachschaun, da ich diese Info selbst nicht brauche...). > Das erzeugt ja auch Warnungen.;-) Die lassen sich aber vermeiden... > Ich lese mir das jedenfalls durch und > beurteile ob es wichtig ist. Das mache ich auch, falls welche auftreten. Es versuche es aber zu vermeiden. > Ob du nun die 2 Nullen anhängst oder der > Assembler ist doch egal. Solange es nur eine Stringterminierung ist, ist das völlig egal, habe ich auch nie anders behauptet. Aber wenn man sich das angewöhnt, dann macht man das (unbewusst, aus Routine) auch dann, wenn die Tabelle Daten enthält und die zusätzliche (im Quelltext nicht vorhandene!!!) Null den Index durcheinander bringt. > Wichtiger wäre mir im Bedarfsfall die 2 Byte > noch zu haben. Ich habe mich heute erst mächtig über 26 Byte gefreut die > ich freisetzen konnt. Das sind immerhin 13 Befehle. Naja, sooooo knapp ist es bei mir selten. > >>Die "Nullpunkte" beider LCD-Zeilen liegen 64 Bytes auseinander > Hoffentlich irrst du dich da nicht. Schaue dir doch das Datenblatt, > welches Axel oben angehangen hat, mal richtig an. Irrtum... Im Datenblatt, das Axel angehangen hat Beitrag "Re: Pollin LCD1602 keine Anzeige" stehen gar keine Adressen. Aber da steht (auf Seite 2 oben) etwas gaaaaaanz Wichtiges betreffs Länge der Leitungen zum LCD. ;-) Du meinst vermutlich das Pollin-Datenblatt, das ich gepostet habe: Beitrag "Re: Pollin LCD1602 keine Anzeige" > Ich vermisse > jedenfalls ein 0x.. oder $ oder Hex in der Darstellung. Die vermisse ich auch. Aber ich halte das für einen Fehler beim Abschreiben. Denn ich mag nicht glauben, dass man beim 1601-LCD eine "Spezialversion" des HD44780 eingesetzt hat, bei der die (Set DD-RAM-Address-) Basisadresse der zweiten DD-RAM-Zeile anders ist als bei allen anderen HD44780-LCDs. Ich verlasse mich da eben nicht nur auf eine einzige Informationsquelle. Im Datenblatt des HD44780 (Seite 11/12) sehe ich, dass die Adresszuordnung bei Initialisierung als einzeilig oder zweizeilig unterschiedlich ist. Bei einzeilig ist der DD-RAM von Adresse $00 bis $4f durchgehend ansprechbar. Die meisten LCDs sind aber zweizeilig adressiert, da teilt sich der DD-RAM in zwei Bereiche auf, $00 bis $27 für die erste Zeile und $40 bis $67 für die zweite Zeile. Ich hänge mal ein anderes Dokument an, in dem die Adressen ganz gut beschrieben sind. Man beachte die Tabelle auf Seite 6. Achja, wenn es sein muss, kann ich Dir noch ein paar Datenblätter zu HD44780-LCDs posten (2x16, 2x24), in denen die Basis-Adresse für die zweite Zeile auch mit 64 (192) angegeben ist. > > Schönen Tag noch, Uwe Den wünsche ich Dir auch... Hannes
Hallo an alle, ich wende mich nun nochmal an euch. Ich habe nun meinen Code so geändert: .include "m8def.inc" .def temp10 = r16 ldi temp10, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp10 ldi temp10, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp10 rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ;text1 ausgeben ldi temp1 , $A8 rcall lcd_command ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) rcall lcd_flash_string ;text 2 ausgeben loop: rjmp loop text1: .db "TESTABCD",0,0 ; String, durch '0' angeschlossen text2: .db "12345678",0,0 ; String, durch '0' angeschlossen .include "lcd-routines.asm" Mein Display zeigt nun 'TESTABCD12345678' :-) Nur sollte nach meiner Einstellung in den LCD-Routines der Cursor blinken. Tut er aber nicht. ldi temp1, 0b00001111 ; Display on, Cursor on, Cursor blinken rcall lcd_command Das ist doch OK? Axel
Hallo, kann mir nochmal jemand einen Tipp geben, warum der Cursor nicht blinkt? Vielen Dank Axel
Hi!
Hatte ich also doch recht, $A8 ist 2.Zeile Zeichen1. Wohl doch nicht so
ganz HD44780.
>kann mir nochmal jemand einen Tipp geben, warum der Cursor nicht blinkt?
Gegenfrage: An welcher Stelle würdest du den Kursor denn vermuten?
Mal so als Tip, momentan ist autoshift eingeschaltet.
Schreibe mal:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ldi ZL, LOW(text1*2)
ldi ZH, HIGH(text1*2)
rcall lcd_flash_string ;text1 ausgeben
ldi temp1 , $A8
rcall lcd_command
ldi ZL, LOW(text2*2)
ldi ZH, HIGH(text2*2)
rcall lcd_flash_string ;text 2 ausgeben
ldi temp1 , $80
rcall lcd_command
:
:
Wenn es jetzt nirgends blinkt müssen wir nochmal schauen, aber ich denke
es blinkt.
Viel Erfolg, Uwe
Hallo Uwe, jetzt bin ich richtig happy :-), es funzt. Text korrekt. Der Cursor blinkt an der ersten Stelle. Cursor ein- und ausschalten funzt prima. Für alle, die auch das LCD 161F BL verwenden hier mein Code: .def temp10 = r16 ldi temp10, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp10 ldi temp10, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp10 rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ldi ZL, LOW(text1*2) ldi ZH, HIGH(text1*2) rcall lcd_flash_string ;text1 ausgeben ldi temp1 , $A8 rcall lcd_command ldi ZL, LOW(text2*2) ldi ZH, HIGH(text2*2) rcall lcd_flash_string ;text 2 ausgeben ldi temp1 , $80 rcall lcd_command loop: rjmp loop text1: .db "Hallo, i",0,0 ; String, durch '0' angeschlossen text2: .db "ch bin's",0,0 ; String, durch '0' angeschlossen .include "lcd-routines.asm" Besten Dank an Uwe
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.