Hallo!
Ich habe auf der Seite mathar.com mir das LCD Tutorial angeschaut.
Zum testen habe ich einfach mal den kompletten Quellcode kopiert und
lediglich die Tasten angepasst (statt Port 6 auf Port 1).
Allerdings erscheinen auf meinem 2*16 LCD mit HD44780 Controller nur
schwarze Kästchen und das auch nur in der ersten Reihe.
Ich habe die Verkabelung schon zweimal kontrolliert und neu gemacht,
aber das Problem ist das gleiche. Durchgemessen habe ich die Leitungen
auch, daran sollte es eigentlich nicht liegen. Hat jmd eine Idee, was
ich falsch gemacht haben köntte?
Danke
Der Code (*) hängt ganz essentiell davon ab, dass die Wartefunktion wie
vorgesehen funktioniert und damit die Mindesttimings aus dem LCD
Datenblatt eingehalten werden!
Werden die Timings nicht eingehalten, kann der µC das LCD nicht
initialisieren (Softreset ausführen) und es kommt zu den typ.
einzeiligen Klötzchen.
1
voidwait(unsignedinti)// delay function
2
{
3
unsignedintj;
4
for(j=0;j<i;j++);
5
}
Anm. aus dem Tutorial
[zitat]
void wait(unsigned int i)
Diese Funktion wird benötigt, da das LCD-Display eine gewisse Zeit
braucht, bis es die angelegten Befehle ausgeführt hat. Die genauen
Zeiten hängen von der Taktrate des MSP430 ab und sind auf Seite 191 des
Datenblattes zu finden.
[/zitat]
Es gibt Compiler z.B. den GCC, die optimieren Code wie obiges leeres
for gnadenlos weg. Da würde ein volatile unsigned int j; helfen bzw.
eine bessere Wartefunktion.
*
Hardware: http://mathar.com/msp_lcd1.html
Software: http://mathar.com/msp_lcd2.html
C-Source: http://mathar.com/lcd_code.c
Leider weiß ich nicht von welchem Datenblatt er redet. Ich habe einen
32kHz und 8Mhz Quarz am MSP430.
Als Compiler nutze ich IAR Workbench. Ich versuche trotzdem mal das
volatile
Da ist das Datenblatt des verwendeten MSP430 gemeint: MSP430F149.
Soweit ich dort im Text lese, wird der mit "Uhrenquarz mit 32,768 KHz"
betrieben. Vergleicht man das Headerboard bei Olimex mit dem Foto im
Tutorial, findet man aber keinen Uhrenquarz auf dem Tutorialboard,
sondern man sieht einen installierten Quarz im "optional high frequency
crystal (socket)". Leider ohne Frequenzangabe.
Im Endeffekt hilft wohl nix. Du musst dir eine zuverlässige
Wartefunktion schreiben oder beschaffen und austesten.
was ist denn eine zuverlässige Wartefunktion?
das mit dem volatile funktioniert auch nicht, und die Zeiten hab ich
verdoppelt, aber bringt irgendwie auch kein Erfolg.
Ich wäre schon glücklich mal ein einzelnes Zeichen zu sehn :)
Ich würde einen Zwischenschritt machen und mich dabei nur auf die
Aufgabe Wartefunktion konzentrieren. Das LCD ist dabei als
Erfolgskontrolle bescheiden: Es kann nur 'geht' oder 'geht nicht'
Es hängt von deinen Möglichkeiten ab, wie du mehr Infos bei der
Entwicklung bekommst. Oszi wäre super, aber das ist bei Einsteigern
selten vorhanden. Aber eine simple LED und ein passender Vorwiderstand
ist meistens vorhanden oder kann aus irgendeinem Teil gemopst werden.
Und Uhren hat man viele...
Also schreibt man sich ein Blinkprogramm mit dem
Wartefunktion-Kandidaten. Laut Code oben soll wait(20000) 10ms warten.
Damit kann man sich eine Funktion schreiben, die z.B. 0,5 s wartet (50
Aufrufe wait(20000)). 0,5s LDE an, 0,5s LED aus und dein Projekt sollte
einen Puls um 60 Schläge pro Minute haben...
Beim Launchpad gibt es ein Beispiel bei dem ähnliche Funktionen wie von
Peter angesprochen benutzt werden. Sie stützen sich auf eine Build-In
(intrinsic) Funktion __delay_cycles(). Dort ist auch die Verlängerung
per Wartezeit zu sehen:
http://processors.wiki.ti.com/index.php/Playing_The_Imperial_March
ich hab jetzt eine delay funktion geschrieben, die auch bestens
funktioniert, was meine blinkende led ja auch beweist.
Allerdings habe ich immer noch das gleiche Problem mit dem Display. Ich
hab die geforderte Zeit abgewartet, aber die erste Reihe bleibt mit
Blöcken gefüllt.
Hat vielleicht noch jmd eine idee, was ich falsch gemacht haben könnte?
Welche LCD-Lib benutzt Du denn?
Das HD44780 Datenblatt ist etwas irreführend. Alle Kommandos bis
einschließlich des 4Bit-Mode Kommandos müssen von einem Delay gefolgt
werden!
Wenn Du ein Zyklus-Delay hast, ist das schonmal gut. Dann kannst Du Dir
delay_us und delay_ms selber schreiben, indem Du einmal die Taktfrequenz
definierst (F_CPU) und dann die Umrechnungformel als Argument
reinschreibst. Konstanten rechnet der Compiler ja selber aus.
Peter
Was soll das werden?
Der E-Puls muß minimal 0,45µs sein, 15000µs ist also reiner Blödsinn.
Der E-Pin ist immer low und wird nur kurz gepulst, nachdem alle
anderen eingestellt sind.
Lies das Datenblatt, nimm die Minimalzeiten vielleicht zur Sicherheit *2
aber nicht *30000.
Peter
Freak schrieb:> delay_us(500); // clear display braucht was laenger
Seit wann sind 500µs >= 1.52ms ???
Und E darf erst high gehen 60ns nach RS setzen, nicht gleichzeitig!
Lies doch bitte endlich mal das Datenblatt.
Peter
ich komme immer noch nicht klar. irgendwie scheint dieser mathar code
nicht zu funktionieren. Ich werde wohl oder übel mir alles selber
programmieren müssen.
hi, ich habs immer noch nicht hinbekommen...
kann man die LCD library for HD44870 based LCD's von Peter Fleury
umschreiben für einen MSP430?
Wenn ja könnte mir jmd. einen Hinweiß geben, was man da wie ändern
müsste?
Ich kenne mich mit Atmel leider nicht aus.
Danke!
Versuch mal so:
void LCDInit(void)
{
P4OUT=0x30;
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
P4OUT=0x30;
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
P4OUT=0x30;
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
P4OUT=0x38; // 8 bit operation, 2-zeilen-display, 5*8 dot
font
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
P4OUT=0x0E; // display anschalten, cursor an, cursor
blinkt nicht
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
P4OUT=0x06; // cursorrichtung: nach rechts; kein
display-shift
P5OUT=0x04; // RS und R/W low, E high
LCDClock(); // befehl ausfuehren
}
Kann Dein Compiler denn keine Bitvariablen?
Dann könntest Du mein Beispiel einfach mal ausprobieren (RW muß auf 0V
sein).
Freak schrieb:> Allerdings erscheinen auf meinem 2*16 LCD mit HD44780 Controller nur> schwarze Kästchen und das auch nur in der ersten Reihe.
Dann stimmt noch nichtmal das LCD-Init.
Peter
Ja das LCD_init ist falsch nur weiß ich nicht wie es richtig geht.
Der Code von oben funktioniert nicht. Auch mit den passenden Wartezeiten
Nach datenblatt tut sich nichts.
Was ist denn dein Beispiel und was ist mit einer Bitvariable gemeint?
Mein Compiler beherscht das sicher auch, ich weiß nur nichts damit
anzufangen.
Der Code passt. Sag mal hast du eventuell den Kontrast viel zu weit
aufgedreht? Dann sieht man auch nur schwarze Klötzchen.....
P4OUT und P5OUT sowie die Bits in der Header Datei musst du natürlich an
deine Beschaltung anpassen. Daher hab ich das ja in einer Header Datei,
da muss man nur dort einmal die Ports/Pins angeben.
ja hab alles angepasst, habe auch etwas den Kontrast runter gedreht ist
bei ca 0,9 V
die Klötzchen sind dann weg
zum Test:
for(;;)
{
LCD_Char('a');
}
sollte mir ja ein a ausgeben, aber ich seh da leider nichts.
Dazu sollte im Datenblatt deines LCD und deines MSP430 etwas stehen.
Du willst die HIGH Pegelspannung des MSP430 bei einem Ausgangspin mit
der HIGH Pegelspannung des LCD bei einem Eingangspin vergleichen.
Wenn da keine Überlappung vorhanden ist, brauchst du einen
Pegelwandler.
Wenn das stimmt was in den Datenblättern steht, gibs kein Problem.
Der MSP macht zw. 3 und 3.3V und das LCD soll ab 2.7 V gehen. Naja tuts
aber nich :(
Hast du inwischen einen besseren Code als den vom 22.01.2011 17:27? Mit
den korrekten Wartezeiten nach jeden Befehl gemäß LCD Controller
Datenblatt nach jedem LCDClock(). Bisher hast du typ. delay_us(6); plus
+- paar zerquetschte für den Rücksprung aus LCDClock(), Setzen des
nächsten Kommandos und Aufruf des nächsten LCD-Kommandos - viel zu
wenig!
Sind folgende Befehle aus der Init für den LCD Controller bereits mit
dem Datenblatt abgeklärt? Hast du einen Link auf das Datenblatt oder ein
PDF?
P4OUT=0x38; // 8 bit operation, 2-zeilen-display, 5*8 dot font
P4OUT=0x0E; // display anschalten, cursor an, cursor blinkt nicht
P4OUT=0x06; // cursorrichtung: nach rechts; kein display-shift
Bist du sicher, dass dein LCD nicht die übliche Reset-Sequenz zu Beginn
der LCDInit braucht und du direkt mit dem 'Funktion Set' (0x38) los
legen kannst?
LCDs können zickig sein, wenn die Initialisierung per Software schief
geht. Machst du einen einen kompletten Power-Up-Zyklus (Schaltung
AUS-AN) nach dem Flashen vor dem Testen (gut) oder nicht (schlecht)?
Habe den Code von Christian R. versucht. Das Datenblatt
http://www.mikrocontroller.net/part/HD44780 Seite 45 so hab ich es
versucht.
Christian sagt ja der Code funktioniert, das glaube ich ihm auch.
Verkabelt hab ich alles zum x-ten mal, durchgemessen auch. Ich bin mir
sicher das die LCDs zickig sind :)
Ich mache immer alles aus und debugge neu und hoffe jedes mal etwas zu
sehn :)
Freak schrieb:> kann es sein, dass die 3 V Flanken vom MSP430 doch nicht ausreichen für> manche HD44780 ?
Gute Frage - also mit 3,3V klappt es definitiv - hatte noch nie ein
Display, das darauf nicht reagiert hat.
Eins muss ich mal loswerden...auch wenn nicht hilfreich für den TO.
Ich wunder mich jedesmal, wenn die ganzen HD44780 LCDs bei so vielen
nicht funktionieren. Ich hatte bis jetzt noch kein einziges, was nicht
geklappt hat.
Als ich damals mein erstes zum Leben erwecken wollte, lief es auf
Anhieb. Und das ohne 3-maliges initialisieren und OHNE Wartezeiten
zwischen den einzelnen Befehlen (diese mache ich selbst jetzt nicht
immer rein, sofern es im Test ordentlich läuft). Ansonsten begnüge ich
mich mittlerweile dann eher mit den Timern, um die Anforderungen
einzuhalten.
Wichtig dabei wäre aber noch, dass ich meine MSPs damals mit dem
internen DCO betrieben habe, welcher ja nur auf ~1MHz läuft ohne
Initialisierung. Vielleicht hätte es bei 8MHz auch anders ausgesehen....
Freak schrieb:> Ich habe einen> 32kHz und 8Mhz Quarz am MSP430
Aber wenn du einen 32kHz-Quarz dran hast, dann ist das doch optimal für
einen exakten Timer bezüglich der ms-Timings beim Display.
ich nehm keinen Timer, ich benutze die Wartefunktion des Compilers. Die
funktioniert, habs am Oszi nachgemessen.
BTW:
Läuft der DCO eigentlich immer mit den rund 1MHz von Haus aus, wenn man
nichts anderes einstellt? der ist ja auch die Quelle für den MCLK und
SMCLK, wenn mich nicht alles täuscht.
Freak schrieb:> Läuft der DCO eigentlich immer mit den rund 1MHz von Haus aus, wenn man> nichts anderes einstellt?
Ja, eigentlich schon. Ich weiß nur nicht, wie es bei älteren Derivaten
ist...
Das einzige Display, was ich mal hatte, und was gezickt hat, was so ein
komisches 4x20 von LCD-Module.de. Das hatte ich am MSP430 SPI und hab
erst später gemerkt, dass das gerne die Bitorder per SPI gedreht haben
will. Der alte MSP430F149 konnte das aber noch nicht. Ansonsten liefen
alle Module anstandslos. Der Code funktioniert definitiv, war aus
unserer Projektarbeit im 7. Semester. Da war ein MSP430F169 am Stino
Reichelt 4x20 Display.
So ersteinmal ein großes Danke an Helfer. Das hier ist das mit Abstand
beste Forum, dass ich kenne. Es funktioniert endlich! Ich habe meine
Krempel zu einem Bastlerfreund geschleppt und nach einiger Zeit ist ihm
aufgefallen, dass die Massen von LCD und dem MSP430 verbunden werden
müssen! Es hat also eigentlich der Code schon mehr oder weniger die
ganze Zeit gestimmt. Tja aber 0V sind halt nicht immer 0V und so hat im
Debugger und logisch alles gestimmt, aber das hat nicht viel genützt.
Ein gutes hat die Sache dann doch noch gehabt, ich kenn die Befehle und
die Timings des HD44780 sogut wie auswendig und ich werde sicherlich
nicht noch einmal den Potentialausgleich vergessen.
Von daher kann das Problem als "gelöst" markiert werden :)