mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD mit PCF8574 Frage


Autor: Pete (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche, ein LCD (HD44780 komp.) mit einem PCF8574 zum Leben zu 
erwecken.

Irgendwie funktioniert aber die Initialisierung nicht. 
Kontasteinstellung ist wohl ok, ich sehe teilweise die Zeichenmatrix.

Den 8574 kann ich ansprechen, das ist soweit ok.
I2C Lib ist von Peter Fleury.
Anbindung wie bei ASURO (siehe Bild).

Sorry, dass der Code etwas lang geworden ist.

Hier der InitCode:
////// PCF8574 PINS

#define LD4  0  // Pin to Data Bus 4
#define LD5  1  // Pin to Data Bus 5
#define LD6  2  // Pin to Data Bus 6
#define LD7  3  // Pin to Data Bus 7

#define LRS  4  // Pin to RS Pin (Register Select)
#define LRW  5  // Pin to Read/Write Pin
#define LEN  7  // Pin to Enable Pin
#define LBL  6  // Backlight Pin, not used

#define LCD_INIT  {0b00000010,0b00001000, 0b00000000, 0b00001000, 0b00000000, 0b00000001, 0b00000000, 0b00000110, 0} // siehe Seite 18 Datenblatt

void InitLCD(void)
{
  unsigned char init[] = LCD_INIT;
  unsigned char i = 0;

  SetIOLCD(0, LCD_EN);              // Start LCD Control, EN=0
  _delay_ms(15);                    // Wait LCD Ready

  CommandLCD( LCD_8BIT | (LCD_8BIT >> 4) );
  _delay_ms(5);
  CommandLCD( LCD_8BIT | (LCD_8BIT >> 4) );
  _delay_ms(1);
  CommandLCD( LCD_8BIT | (LCD_8BIT >> 4) );
  _delay_ms(1);
  CommandLCD( LCD_8BIT | (LCD_4BIT >> 4) );
  _delay_ms(1);

  while (init[i] != 0x00)  // Hier sollten die 8 Kommandos geschickt werden
  {
    CommandLCD(init[i]); i++;
  }
  _delay_ms(1);
}

void CommandLCD(unsigned char command)
{
  if (command == LCD_HOME)  lineLCD = cursorLCD = 0x00;
  SetIOLCD(0, LCD_RS);
  SetDataLCD(command);
}

/* --------------
  LCD IO Ports schreiben
  \param  setCommand an - oder auschalten
  \param  bits  zu setzende bits
*/
void SetIOLCD(unsigned char setCommand, unsigned char bits)
{
  if (setCommand == 1)
    portLCD |= bits;
  else
    portLCD &= ~bits;

  i2c_start_wait(LCD_DEV+0);
  if (i2c_write(portLCD)) uart_puts("i2c Write failed.\n"); 
  i2c_stop();
}
/*------------
  LCD Daten schreiben
  \param  data auszugebende Date
*/
void SetDataLCD(unsigned char data)
{
  unsigned char dataPins;             // Pin Compatibility

  // Set First Nibble Data to DataPins on PCF8574
  dataPins &= 0x00;
  dataPins |= ((data & 0x80) >> 7) << LD7;
  dataPins |= ((data & 0x40) >> 6) << LD6;
  dataPins |= ((data & 0x20) >> 5) << LD5;
  dataPins |= ((data & 0x10) >> 4) << LD4;

  SetIOLCD(0, LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7); //Clear old Data Bit[7..4])
  SetIOLCD(1, dataPins);             // Strobe High Nibble Command
  SetIOLCD(1, LCD_EN);               // Enable ON
  _delay_ms(1);
  SetIOLCD(0, LCD_EN);              // Enable OFF

  // Set Second Nibble Data to DataPins on PCF8574
  dataPins &= 0x00;
  dataPins |= ((data & 0x08) >> 3) << LD7;
  dataPins |= ((data & 0x04) >> 2) << LD6;
  dataPins |= ((data & 0x02) >> 1) << LD5;
  dataPins |= ((data & 0x01) >> 0) << LD4;

  SetIOLCD(0, LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);     // Clear old LCD Data (Bit[7..4])
  SetIOLCD(1, dataPins);            // Strobe Low Nibble Command
  SetIOLCD(1, LCD_EN);              // Enable ON
  _delay_ms(1);
  SetIOLCD(0, LCD_EN);              // Enable OFF
  _delay_ms(1);                     // Wait LCD Busy
}

Autor: Pete (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Und die Beschaltung gemäß Asuro als Anhang.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Pete (Gast)

>ich versuche, ein LCD (HD44780 komp.) mit einem PCF8574 zum Leben zu
>erwecken.

[[Port-Expander PCF8574]]

>Irgendwie funktioniert aber die Initialisierung nicht.
>Kontasteinstellung ist wohl ok, ich sehe teilweise die Zeichenmatrix.

>Sorry, dass der Code etwas lang geworden ist.

Das gehört in den Anhang. Netiquette

Ich sehr erstmal keinen direkten Fehler.

MFG
Falk

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pete,

uberpruefe ob das "E" Strobe signal tatsaechlich funktioniert. Mir kommt 
vor Du musst das E signal mit den Rest der Saten ORen. Das LCD nimmt nur 
dann die neuen Daten an, wenn die Daten auf dem Datenbus liege und 
danach das E Signal getatset wird.



----\_____________________________________  RS

(je nach CMD oder Daten Mode)

__ _______________________________ ______
__X_______________________________X______  Datenbus DB4-DB7
     (Gueltiges Neues Datenwort)      (Naechstes...)
                          __
_________________________/  \_____________  E Strobe
                            ^
                            |___ Daten werden erst hier vom HD44780
                                 angenommen (gespeichert)

So will das LCD die Ansteuerung sehen. Deshalb wirst Du die PCF8874 
Daten drei mal senden muessen:

1) Datenwort = ((DB4-7) | RS=X | E=0)
2) Datenwort = ((DB4-7) | RS=X | E=1)
3) Datenwort = ((DB4-7) | RS=X | E=0)

Versuche es mal auf diese Weise. Du koenntest uebrigens auch das E 
signal direkt von einem zusaetzlichen Pin Deines MCU ansteuern. Dann 
wuerde ein PCF8574 Wort genuegen.

Gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleine Berichtigung: Die Reihenfolge der PCF8674 ist bei meinem Beispiel 
nur wahlkuerlich angenommen. Musst Du entsprechend umanedern.

Gerhard

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Gerhard

Das mit dem Enable dachte ich wird in den letzten 4 Zeilen des 
geposteten Codes gemacht.
Daten Anlegen und dann Enable High und High->Low setzen. (Siehe 
SetDataLCD)

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuche es mal so:

void SetDataLCD(unsigned char data)
{
  unsigned char dataPins;             // Pin Compatibility

  dataPins = data >> 4; // Schiebe DB4-7 in P0-P3 Bitbereich
  SetIOLCD(1, dataPins & 0x0F ); // P5=0,P4=1,P7=0, Daten=P0-3
  SetIOLCD(1, dataPins | 0x80);  // Setze P7
  SetIOLCD(1, dataPins & 0x7F ); // Clear P7

  // Sende den zweiten Daten Nibble
  dataPins = data & 0x0F; // Nur DB0-3 werden gebraucht, P4-P7=0
  SetIOLCD(1, dataPins & 0x0F ); // P5=0,P4=1,P7=0, Daten=P0-3
  SetIOLCD(1, dataPins | 0x80 ); // Setze P7
  SetIOLCD(1, dataPins & 0x7F ); // Clear P7

}

Ich wuerde SetIOLCD umaendern, so dass es nur ein 8-bit Datenwort 
aussendet und die Manipulierung der Busbits in der Anwender Routine 
vorgenommen wird.

Der Wert von P4 muss je nach DATEN Mode oder Command Mode eingestellt 
werden. P5 kann immer auf Null liegen solange BUSY nicht gelesen wird.

Jetzt sieht der HD44780 die Daten waehrend des Strobing des E Signals 
weil sich ja nur der Inhalt des P7 bits (E) aendert und alle anderen 
Daten anliegen.

Man koennte spaeter einen One-Shot an P7 anhaengen, welcher den E Pulse 
erzeugt und erspart sich die drei PCF8574 Sendungen bis auf eine.

Gerhard

Autor: Gerhard. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pete,

habe es mir nicht nehmen lassen, das mal selber aufzubauen und hat bei 
mir mit einem PIC18F8722, PCF8574A und einem zweizeiligen LCD auf Anhieb 
funktioniert. Werde spaeter mein Test Program hier im Anhang beilegen.

Gruss,
Gerhard

Autor: Gerhard. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pete,

im Anhang das versprochene Demo Programm. Also nicht aufgeben;-).

Es geht auf alle Faelle mit dem PCF8574A als LCD Bus Treiber. Die 
Zugriffsgeschwindigkeit ist sehr gut.

Wenn man eine kleine Zusatzschaltung verwendet liesse sich pro PCF8574 
dann ein Nibble uebertragen.

Werde mir warscheinlich selber eine kleine LCD Huckepack-platine 
erstellen. Ist auf jeden Fall sehr bequem ein LCD ueber I2C anzusteuern. 
Man kann dann die unbenutzten Bits fuer die LED Einschaltung verwenden. 
Mit einen billigen 8-bit I2C DAC koennte man auch noch den Kontrast 
einstellen. Vielen Dank mich auf diesen Weg hinzuleiten.

Gruss,
Gerhard

Autor: Pete (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gerhard,

danke für die bildlichen LCD Grüße :-)

Jetzt funktioniert es auch bei mir. Das mit dem Enable hat wohl nicht 
geklappt.

Auf jeden Fall eine super Sache so ein LCD über I2C :-)

Viele Grüße,
Pete

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Pete!

danke fuer die Erfolgsmeldung. Freut mich sehr;-). Dein Problem hat mir 
auch geholfen, da ich jetzt selber einen Treiber dafuer habe. Fuer mich 
war das auch das erste Mal einen PCF8574 anzusteuern.

Das tolle mit dem I2C LCD Interface ist jetzt, dass man nun bequem mehr 
als ein LCD ansteuern kann.

Ich habe vor eine kleine Platine oder einen Lochrasteraufbau zu 
verwirklichen der Huckepack hinter dem LCD sitzt. Mit den zwei 
unbenutzten PCF8574 Ausgaengen koennte man dann noch schon die B.L. LEDs 
schalten (3 Helligkeitsstufen).

Gruss,
Gerhard

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur ein Tip nebenbei: Ein LCD mit eingebautem PCF8574 kann man bei 
Oppermann fertig kaufen: 
http://www.oppermann-electronic.de/html/januar_2008.html (Das "LCM 
015"). Wie das aussieht, sieht man hier: 
http://forum.lcdinfo.com/viewtopic.php?p=6887&sid=...

...und die Anschlußbelegung wird hier verraten (auf polnisch, 2. Beitrag 
von oben): 
http://www.elektroda.net/uzytkowa/plmiscelektr/12_...

Netterweise ist auch gleich die Portzuordnung angegeben. Wie man in 
einem anderen Forum liest, bedeutet "Podœwietlenie" 
Hintergrundbeleuchtung.
Das Teil ist also ein industriestandard-kompatibles LCD mit eingebautem 
I2C-Portbaustein, fast genauso wie die in diesem Thread beschriebene 
Selbstbaulösung. Nur ao als kleiner Hinweis, nicht als Werbung 
mißzuverstehen - Ich bekomme keinerlei Provision.

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,

vielen Dank fuer die Hinweise und Links. Immer gut zu wissen.

Gruss,
Gerhard

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.