Ich versuche jetzt seit ungefähr einer Woche, mein LCD zu initialisieren, und es ist mir ziemlich peinlich zu sagen, dass ich bisher erfolglos war. Ich habe dies in der Vergangenheit getan, und ich erinnere mich, dass es ein wenig schwierig war, die Initialisierungssequenz genau richtig hinzubekommen, aber an diesem Punkt denke ich, dass ich die Implementierung vollständig überprüft habe und es einfach nicht funktioniert.
Aufstellen:
Hier sind Dinge, die ich bisher zum Testen gemacht habe:
for
SchleifenDoch nach all dem kann ich nichts auf dem LCD anzeigen! Hier also meine Fragen:
Mein Code sieht so aus:
void InitializeLcd()
{
DelayTicks( 10000);
// 4 bit interface, 2 lines, 5x8 characters
// the spec sheet shows the 0x20 part of 0x28 getting sent an extra time
// so I used a special function to deal with this case. This just sends
// the 0x20 part and ignores the 0x08 part.
SendLcdUpperNibble( COMMAND, 0x28);
SendLcdByte( COMMAND, 0x28);
DelayTicks( 1000);
// Display on, cursor off, blink off
SendLcdByte( COMMAND, 0x0C);
DelayTicks( 1000);
// clear display
ClearLcd();
// Entry mode set - increment cursor, no display shift
SendLcdByte( COMMAND, 0x02);
DelayTicks( 1000);
// Set write to DDRAM mode since we'll just be sending data from now on
SendLcdByte( DATA, 0x48);
SendLcdByte( DATA, 0x65);
SendLcdByte( DATA, 0x6C);
SendLcdByte( DATA, 0x6C);
SendLcdByte( DATA, 0x6F);
}
void ClearLcd()
{
// Clear display
SendLcdByte( COMMAND, 0x01);
DelayTicks( 1000);
}
void SetRS( int value)
{
if( value == 0)
P2OUT &= ~RS;
else
P2OUT |= RS;
}
void SetRW( int value)
{
if( value == 0)
P2OUT &= ~RW;
else
P2OUT |= RW;
}
void SetE( int value)
{
if( value == 0)
P1OUT &= ~E;
else
P1OUT |= E;
}
void DelayMs( int delay)
{
int ctr;
int ms = delay * 100;
for( ctr=0; ctr<ms; ctr++);
}
void DelayTicks( int ticks)
{
int ctr;
for( ctr=0; ctr<ticks; ctr++);
}
void SendLcdByte( unsigned char command_0_or_data_1, unsigned char command)
{
SendLcdUpperNibble( command_0_or_data_1, command);
// send the lower nibble next
// special thank you to ToyBuilder for catching my missed bit-shift in the following line
// I also had the mask on P1OUT incorrect, presumably because I messed up the command mask and just made it match that.
P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0x0F);
Strobe( command_0_or_data_1);
}
void SendLcdUpperNibble( unsigned char command_0_or_data_1, unsigned char upper_nibble)
{
P1OUT = (upper_nibble & 0xF0) | (P1OUT & 0x0F);
Strobe( command_0_or_data_1);
}
void Strobe( unsigned char command_0_or_data_1)
{
SetRS( command_0_or_data_1);
SetRW( 0);
DelayTicks( 1000);
SetE( 1);
DelayTicks( 1000);
SetE( 0);
}
Das einzige, was ich sagen kann, ist, dass das LCD so aussieht, als würde es flackern, wenn ich über SendLcdByte gehe und ihm Zeichendaten sende. Wenn ich alles durchschaue, sieht es sicher so aus, als würde ich die Bits richtig umdrehen ...
BEARBEITEN - Ich habe ein neues LCD aufgelötet und dieses Mal versucht, die unbenutzten Datenpins (D0-D3) getrennt zu lassen (dh schwebend). Es gab keinen Unterschied. Das LCD flackert immer noch, wenn ich initialisiere. Ich warte jetzt 100 ms auf alle Verzögerungen, einschließlich einer Verzögerung beim Stroben von E. Ich habe auch Vcc vom Launchpad-FET-Bereich getrennt und versorge jetzt nur den MSP430 und das LCD von meinem Labornetzteil.
BEARBEITEN #2 - Ich ging zu einem 3,3-V-LCD und alles fing auf magische Weise an zu arbeiten. Vielen Dank an ToyBuilder für das Auffangen eines dummen Codefehlers, als ich mit dem 5-V-LCD debuggte. Nach dem Austausch wurde das LCD ordnungsgemäß initialisiert. Ich zeige derzeit Müll anstelle von "Hallo" an, aber das hat nichts mit dieser Frage zu tun.
BEARBEITEN #3 -- habe meinen Anzeigefehler gefunden -- ich habe 0x06 für den Eingabemodus anstelle von 0x02 gesendet. Ich bin mir nicht sicher, warum ich das getan habe, muss ein Tippfehler gewesen sein.
Oh, duh, ich habe deinen Code nicht sorgfältig gelesen - dein send SendLcdByte ist falsch:
void SendLcdByte( unsigned char command_0_or_data_1, unsigned char command)
{
SendLcdUpperNibble( command_0_or_data_1, command);
// send the lower nibble next
// AS WRITTEN:
P1OUT = (command & 0x0F) | (P1OUT & 0xF0);
// SHOULD BE:
P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0xF0);
Strobe( command_0_or_data_1);
}
P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0x0F);
ich mir wünschen, ich könnte eine Entschuldigung machen, wie "Ich bin Legastheniker", aber ich kann nicht. Ich habe die Datenbusbits auf dem Oszilloskop überprüft, muss aber die Bits, die gestrobed werden, erneut überprüfen, da es immer noch nicht funktioniert. Ich probiere jetzt auf dem LCD selbst, anstatt das Steckbrett zu stoßen.Überprüfen Sie die hohen/niedrigen Ausgangsspannungen des Signals vom MSP430 und die Mindestwerte für die Eingänge auf dem LCD.
Eine andere Sache ist, ob Sie zu schnell schlagen – Ihre Quellenliste zeigt nicht, wie Sie die Daten und E-Signale drehen. Wenn Sie nach dem Laden der Datenbits zu früh an E drehen, funktioniert es nicht. Wenn Sie E nicht lange genug gedrückt halten, damit das LCD die eingehenden Daten zwischenspeichern kann, funktioniert es nicht. Versuchen Sie, eine Zeitverzögerung zwischen dem Schreiben von D0-D7 und dann zwischen dem Aktivieren und Deaktivieren der E-Leitung hinzuzufügen.
Ich gehe davon aus, dass die Leitungen ausschließlich für die LCDs verwendet werden, sodass es kein Problem mit der Haltezeit gibt. Wenn Sie die Leitungen auch als Bus zu anderen Geräten verwenden, müssen Sie sicherstellen, dass Ihre Daten lange genug gespeichert werden, bevor der Bus für andere Dinge verwendet wird.
Eine Sache, die mich auch einmal ausgetrickst hat, war, dass die Hintergrundbeleuchtung so schwach war, dass ich nicht sehen konnte, dass sie funktionierte.
Der technische Support von Newhaven Display hat mir empfohlen, das LCD auszutauschen und es erneut zu versuchen. Es ist möglich, dass ich es während der Ersteinrichtung beschädigt habe, also werden wir sehen, wie das geht. Die Ergebnisse poste ich hier.
Kann es sein das du die Pins vertauscht hast?
Hin und wieder stieß ich auf LCDs mit umgekehrten Pin-Nummern, entweder auf dem Teil selbst oder auf dem Datenblatt oder auf beiden.
Ich weiß, dass dies wie ein "Ist es eingesteckt?" erscheinen mag. Frage - aber ich persönlich wurde damit überrascht.
* BEARBEITEN *
Ugh, in meinem früheren Kommentar sagte ich, ich solle 0x80 schreiben -- was ich beabsichtigte, war, dass Sie versuchen, den Wert 0x40 oder 0x60 in den Datenleitungen zu halten.
Wenn sich herausstellt, dass die Pins vertauscht sind, würde das Schreiben von 0x40 Strom und Masse über die Datenpins an das LCD anlegen und ihm die Möglichkeit geben, seinen Selbst-Reset durchzuführen. Dies ist möglich, weil ein typisches LCD-Zeichenmodul nur etwa 1 bis 5 mA Strom zieht, was weit innerhalb der Treiberfähigkeit der meisten Ausgänge liegt.
Was ich vermute, ist, dass Sie während der Initialisierung des LCD für kurze Zeit einige 0x6X- und 0x4X-Werte auf Ihr LCD schreiben - und dass das LCD während dieser kurzen Zeit eingeschaltet wird. aber wenn Sie anfangen, andere Werte zu schreiben, schalten Sie es effektiv aus.
*ÄNDERN 2*
Beim Nachschlagen des Datenblatts eines anderen LCDs zur Überprüfung der aktuellen Anforderungen ist mir aufgefallen, dass Sie möglicherweise Ihre Vcc- und Vcontrast-Pins vertauscht haben. Kontrollieren Sie das unbedingt auch!
Ich habe gerade im NHT-C0220AZ-FWS-FTW-Datenblatt (wo Sie oben Ihre schematische Zeichnung erhalten haben) nachgesehen und gesehen, dass der Kontrast Pin 2 und die Versorgungsspannung Pin 3 ist. Dies ist die Umkehrung der Vishay- und Optrex-Teile, in denen Kontrast vorhanden ist ist Pin 3 und die Versorgungsspannung ist Pin 2.
Nun, zum Teufel, sogar der NHD-0420DZ-FSW-FBW von NewHaven hat Kontrast auf Pin 3 und Versorgung auf Pin 2.
David