Forum: Mikrocontroller und Digitale Elektronik Problem LCD über PCF8574AP ansteuern


von Peter (Gast)


Lesenswert?

Hallo

also ich habe eine Bib für die Ansteuerung von einem LCD. Diese 
funktioniert ohne probleme. Jetzt habe ich versucht das LCD mit einem 
PCF8574AP an zuschließen und habe die Bib geändert.
1
lcd_port = 0b00000000;
2
pcf8574ap_writebyte(LCD_ADRESSE, lcd_port);

Habe auch mal die Daten ausgelesen und per UART geschickt. Die 
Datenübertragung funktioniert. Nur das Display reagiert nicht, also wird 
noch nicht einmal initialisiert.

Jemand ne Idee?

von Stephan M. (stmz)


Lesenswert?

so schickt er ja immer 0x00 an den Port Extender.

Ansonsten ist es nicht möglich dir bei deiner knappen 
Problembeschreibung zu helfen. Wir kennen ja deinen Code überhaupt 
nicht.

von Oliver _. (verleihnix)


Lesenswert?

Adresse falsch? Es gibt 2 Typen davon, mal mit und ohne A..

von Wolfgang (Gast)


Lesenswert?

Der pcf8574a scheint mit A zu sein, d.h. die (7-Bit) I2C Adresse liegt 
je nach Hardwarebeschaltung im Bereich 38h und 3fh.

von Peter (Gast)


Lesenswert?

Hallo also Adresse stimmt! Habe die Daten ja auch schon ausgelesen. 
Handelt sich um den PCF8574 AP. Kommunikation funktioniert auch bis 
dahin. Aber auch wenn ich mir die Aktuellen Befehle von dem normalen LCD 
Routine an dem PC schicken lass sind die 1 zu 1 gleich aber das LCD wird 
dann auch schon nicht mehr initialisiert. Könnte es vll an den 
Pausenzeiten hängen?

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Also hier auch mal die LCD.c Hab die Normale Routine also die mit dem 
Atmega8 funktioniert Port geht einfach nur umgeschrieben in dem ich das, 
was ich auf den Port geschrieben hab in eine Variable geschrieben hab 
und diese an den PCF8574AP geschickt. Diesen habe ich genau so 
angeschlossen von den Ports wie am Atmega8.

von Sunny (Gast)


Lesenswert?

Muss das unbedingt 4 bit Modus sein?
Der ist sehr trickreich.Ich würde zuerst mit 8 bit versuchen.
Wenn das jetzt PIC wäre dann könnte ich mehr helfen, weil ich mich damit 
ernst beschäftigt habe.Aber alles schaue ich auch nicht durch mit dem 4 
bit Modus.

von Oliver J. (skriptkiddy)


Lesenswert?

@Peter

Bei Überfliegen sah auf den Ersten Blick alles korrekt portiert aus. 
Vorrausgesetzt die Funktion pcf8574ap_writebyte() tut das, was du dir 
vorstellst.

Zeige bitte alle Funktionen:

- pcf8574ap_writebyte()
- und wenn diese Funktion weitere verwendet, dann zeige diese auch

Sonst kann man dir nicht wirklich helfen.
Am besten du postest alle Header und C-Dateien, von denen die 
LCD_162_TWI.c abhängig ist.

PS. Was genau ist die Adresse, die du bei pcf8574ap_writebyte() 
übergibst?

Gruß Oliver

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo hier die weiteren Dateien. Wie gesagt hab die kommunikation mit 
dem PCF stehen und getestet.

von Peter (Gast)


Lesenswert?

Hat sich nochmal jemand das Prog angesehen?

von Sunny (Gast)


Lesenswert?

Um das zum laufen zu bringen braucht man Leute die davon Ahnung haben 
wie man ein LCD in 4-bit Modus ansteuert.
Und ausserdem müssen sie in C programieren können.
Dann muss man dein Code analysieren und das dauert halt seine Zeit.
Aussedem soltest du selber auch vesuchen rauszufinden warum das nicht 
geht.
Aus meiner Erfahrung hilft dir sowieso niemand wirklich.

von Sunny (Gast)


Lesenswert?

Wenn du sagst an welchen Pins genau dein LCD angeschlossen ist dann 
könnte das auch helfen, weil ich sehe das nicht aus dem Code.

von Sunny (Gast)


Lesenswert?

For a 8-bit data bus, the display requires a +5V supply plus 11 I/O 
lines. For a 4-bit data bus it only requires the supply lines plus seven 
extra lines. When the LCD display is not enabled, data lines are 
tri-state which means they are in a state of high impendance (as though 
they are disconnected) and this means they do not interfere with the 
operation of the microcontroller when the display is not being 
addressed.

The LCD also requires 3 "control" lines from the microcontroller.

Enable (E) This  line allows access to the display through R/W and RS 
lines. When this line is low, the LCD is disabled and ignores signals 
from R/W and RS. When (E) line is high, the LCD checks the state of the 
two control lines and responds accordingly.
Read/Write (R/W) This line determines the direction of data between the 
LCD and microcontroller. When it is low, data is written to the LCD. 
When it is high, data is read from the LCD.
Register select (RS) With the help of this line, the LCD interprets the 
type of data on data lines. When it is low, an instruction is being 
written to the LCD. When it is high, a character is being written to the 
LCD.

Logic status on control lines:

E     0 Access to LCD disabled
       1 Access to LCD enabled

R/W 0 Writing data to LCD
       1 Reading data from LCD

RS    0 Instruction
       1 Character

Writing data to the LCD is done in several steps:

Set R/W bit to low
Set RS bit to logic 0 or 1 (instruction or character)
Set data to data lines (if it is writing)
Set E line to high
Set E line to low

von Bernd (Gast)


Lesenswert?

Sunny schrieb:
> Muss das unbedingt 4 bit Modus sein?

Sunny schrieb:
> Um das zum laufen zu bringen braucht man Leute die davon Ahnung haben
> wie man ein LCD in 4-bit Modus ansteuert.

Wir haben's begriffen, dass DU davon keine Ahnung hast und das als zu 
kompliziert empfindest.
So schlimm ist es nun wirklich nicht, seine Bytes in zwei Hälften zu 
zerlegen. Die Übertragung funktioniert ansonsten genauso wie im 8 Bit 
Modus, nur halt mit 4 Datenleitungen. Wo man aufpassen muß, ist die 
Initialisierung. Insbesondere das Einhalten der Mindestzeiten, damit der 
Controller auf dem Display genug Zeit hat.

von Peter (Gast)


Lesenswert?

Also angeschlossen ist das LCD:

Data7--P7
Data6--P6
Data5--P5
Data4--P4
E------P3
RS-----P2

von Peter (Gast)


Lesenswert?

Also die Initialisierung über den Mikrocontroller-Port klappt es ja. 
Durch das senden über TWI dürfte diese Zeiten ja eher steigen.

von Oliver J. (skriptkiddy)


Lesenswert?

Mach doch mal die alte Verdrahtung und versuch mal:
1
void pcf8574ap_writebyte(unsigned char addressout, unsigned char byte)
2
{
3
    LCD_PORT = byte;
4
}

Gruß Oliver

von Peter (Gast)


Lesenswert?

Oliver J. schrieb:
> Mach doch mal die alte Verdrahtung und versuch mal:

Hi
Danke super Tip. Also das Funktioniert.
Muss also dann an der Verdrahtung oder der Übertragung zum PCF liegen.

von Sunny (Gast)


Angehängte Dateien:

Lesenswert?

Bernd schrieb:
> So schlimm ist es nun wirklich nicht, seine Bytes in zwei Hälften zu
>
> zerlegen. Die Übertragung funktioniert ansonsten genauso wie im 8 Bit
>
> Modus, nur halt mit 4 Datenleitungen.

Sorry, aber so einfach geht es nicht.
Wenn das LCD am "high nibble" ist dann brauchst du ein Code und am "low 
nibble" ein anderes.
In diesem Fall ist er am "high nibble".Und ich habe den code dafür 
leider nur in assembler und für PIC

von Peter (Gast)


Lesenswert?

Sunny schrieb:
> Muss das unbedingt 4 bit Modus sein?

Also das Programm mit dem 4-Bit Modus funktioniert ja ohne Probleme. 
Jetzt bin ich nur daran das Byte was ich sonst auf den Atmega8 Port 
schreib, an den PCF zu senden, welcher mit dem LCD verbunden ist.

von Sunny (Gast)


Lesenswert?

Du kannst nich enfach das Byte senden, weil die RS und RW müssen passend 
gesetzt sein.Die werden in deinem Code warscheinlich separat angesteuert 
und deswegen geht es nicht.

von pompete (Gast)


Lesenswert?

....wie wäre es,wenn du den code einfach an den 4-bit modus anpasst?

Sunny schrieb:
> Sorry, aber so einfach geht es nicht.
> Wenn das LCD am "high nibble" ist dann brauchst du ein Code und am "low
> nibble" ein anderes.

....hä?
wie wäre es,wenn du den code an den 4-bit modus anpasst?

Sunny schrieb:
> In diesem Fall ist er am "high nibble".Und ich habe den code dafür
> leider nur in assembler und für PIC

...und?
wo hast du den her? selbstgeschrieben ist er bestimmt nicht,sonst 
wüsstest du ja wie es funktioniert...
vielleicht analysierst du den code,oder schaust auf der page von 
sprut.de nach,da gibts ein prima tutorial....vielleicht ist "dein code" 
ja von dort....

von Peter (Gast)


Lesenswert?

Sunny schrieb:
> Du kannst nich enfach das Byte senden, weil die RS und RW müssen passend
> gesetzt sein.Die werden in deinem Code warscheinlich separat angesteuert
> und deswegen geht es nicht.

Hab doch eben folgendes probiert und es hat ohne probleme direkt 
funktioniert.
1
void pcf8574ap_writebyte(unsigned char addressout, unsigned char byte)
2
{
3
    LCD_PORT = byte;
4
}

RW hab ich durchgehend auf Low weil ich nur schreiben und nicht lesen 
will. Wichtig sind hier nur Enable und RS. Diese liegen bei dem 
übertragenen Byte an Stelle 2 und 3 weil ich noch 4 Bit am Port frei 
habe.

von pompete (Gast)


Lesenswert?

@sunny
...ups..sehe gerade,hab da was falsch verstanden....nehme alles zurück

von Peter D. (peda)


Lesenswert?

1
lcd_Kommando (0b00100000);  // 4-Bit Modus einstellen

Du bist noch im 8Bit-Modus, also kannst Du kein 4Bit-Kommando senden!

Du darfst nur ein Nibble senden.
Dann wieder warten (>100µs).
Erst danach dürfen 4Bit-Kommados benutzt werden.


Peter

von Peter (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Du bist noch im 8Bit-Modus, also kannst Du kein 4Bit-Kommando senden!

Also der 4 Bit Modus Funktioniert ja am Atmega Port nur noch nicht am 
PCF8574AP habe es ja gestern nochmal getestet.

von Peter D. (peda)


Lesenswert?

Peter schrieb:
> Also der 4 Bit Modus Funktioniert ja am Atmega Port nur noch nicht am
> PCF8574AP habe es ja gestern nochmal getestet.

Genau deshalb!

Direkt am AVR hast Du Glück, weil die 2 Nibble zu schnell hintereinander 
kommen, ignoriert das LCD den 2. 8Bit-Befehl gnädiger Weise.


Peter

von Peter (Gast)


Lesenswert?

Ah ok super Danke habe den Fehler gesehen. Muss also den 4 Bit Befehl 
komplett auf dem Port schicken und nicht in 2x 4Bit Datenpakete. 
Probierts gleich mal aus ob es Funktioniert.

von Peter (Gast)


Lesenswert?

So dann hab ich mal ne super Frage zu dir Initialisierung! und zwar nach 
dem Kommando auf 4 Bit umschalten, muss man dann noch bis zum 
einschalten weiter 8 Bit Daten senden oder muss man 4 Bit senden.
1
void lcd_init()     // keine Werteübergabe von Aufrufposition
2
{
3
  lcd_port = 0b00000000;      // alle Pins auf `0` setzen
4
  pcf8574ap_writebyte(LCD_ADRESSE, lcd_port);
5
  _delay_ms (30);        // warten bis LCD-Controller gebootet ist
6
  lcd_port = 0b00110000;      // 8-Bit Modus einstellen
7
  pcf8574ap_writebyte(LCD_ADRESSE, lcd_port);
8
  lcd_EImpuls ();        // Enable-Impuls 2 mal schicken für vollständige
9
  _delay_ms (5);
10
  lcd_EImpuls ();        // Enable-Impuls 2 mal schicken für vollständige
11
  _delay_ms (1);
12
  lcd_EImpuls ();        // Initialisierung
13
  _delay_ms (1);        // 
14
  //lcd_Kommando (0b00100000);  // 4-Bit Modus einstellen
15
  lcd_port = (0b00100000);      // 4-Bit Modus einstellen
16
  pcf8574ap_writebyte (LCD_ADRESSE, lcd_port);
17
  _delay_ms (5);
18
  lcd_Kommando (0b00101000);  // Funktionsumfang des LCD senden an den Controller 4-Bit, 2 Zeilen, 5x7 Zeichen
19
  lcd_an ();          // lcd anschalten
20
  lcd_Kommando (0b00000110);  // Entry-Mode einstellen
21
  lcd_Sauber();          // Clear Display
22
}

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal der Schaltplan. Ist von myAVR das LCD.

von Sunny (Gast)


Lesenswert?

Ich glabe du brauchst noch lcd_Kommando (0b00001100);  nach dem
lcd_Kommando (0b00101000);

von H. P. Bolliger (Gast)


Lesenswert?

Ich habe Deine 4 angehängten Codeschnipsel grob entwanzt, kompiliert, 
zusammengelinkt und auf mein Avr-System (Atmega128) geladen. An ein 
vernüftiges Debuggen (mit avarice, DDD und Evertool) ist allerdings, 
wegen deiner globalen Variablen "lcd_port". leider nicht zu denken. Ich 
rate dir daher verwende doch lieber, an Stelle Deiner zusammengeklickten 
Patchwork-SW, die bewährte und professionell kommentierte Bib "i2clcd - 
LCD over I2C library" von Nico Eichelmann and Thomas Eichelmann,  die 
auf der I2c-Bib von Peter Fleury basiert.

http://www.mikrocontroller.net/attachment/82786/i2clcd.c.

Darin sieht die "lcd_init"-procedure folgendermassen aus:

//-Display initialization sequence
void lcd_init(void)
{
  lcd_wait_ms(50);
  lcd_write(LCD_D5 | LCD_D4);  //-Set interface to 8-bit
  lcd_wait_ms(10);    //-Wait for more than 4.1ms
  lcd_write(LCD_D5 | LCD_D4);  //-Set interface to 8-bit
  lcd_wait_us(101);    //-Wait for more than 100us
  lcd_write(LCD_D5 | LCD_D4);  //-Set interface to 8-bit
  lcd_wait_us(101);    //-Wait for more than 100us
  lcd_write(LCD_D5);    //-Set interface to 4-bit
  lcd_wait_us(101);    //-Wait for more than 100us

  //- From now on in 4-bit-Mode
  lcd_command(LCD_4BIT | LCD_2LINE | LCD_5X7);
  lcd_command(LCD_DISPLAYOFF);
  lcd_command(LCD_CLEAR);n
  lcd_wait_ms(1);         //-Wait for more than 37us
  lcd_command(LCD_INCREASE | LCD_DISPLAYSHIFTOFF);
  lcd_command(LCD_CURSORMOVE | LCD_RIGHT);
  lcd_command(LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKINGON);
  lcd_command(LCD_HOME);
}

//-Write byte to display with toggle of enable-bit
void lcd_write(unsigned char value)
{
  lcd_write_i2c(value | LCD_E);  //-  Keep enable high
  lcd_write_i2c(value | LCD_E);  //-  Keep enable high
  value &= ~(1 << LCD_E_PIN);
  lcd_write_i2c(value);     //  Set enable to low
}

//-Issue a command to the display (use the defined commands above)
void lcd_command(unsigned char command)
{
  unsigned char lcddata;
  lcddata = command;
  lcddata >>=  4;
  lcd_write(lcddata);
  lcddata = command;
  lcddata &= 0x0F;
  lcd_write(lcddata);
}

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
Noch kein Account? Hier anmelden.