Forum: Mikrocontroller und Digitale Elektronik LCD per I²C keine Reaktion


von 0undNichtig (Gast)


Lesenswert?

Hi, ich habe ein HD44870 LCD per PCF8574 an einen Atmega64 
angeschlossen.
Leider geht da Überhauptnichts :-(

Ich habe die Bibliotheken von http://computerheld.de/i2clcd/ und 
http://scriptkiller.de/avr_pcf8574_hd44780_display.php ausprobiert 
(beider leider nicht Fleur LCD kompatibel :-() aber es will einfach nix 
passieren.

Die PIN Zuordnungen habe ich natürlich angepasst. Der PCF8574 ist 
ansprechbar und auch alle Ports können geschaltet werden. LCD Kontrast 
ist auch dran.

Habe mal die Initialisierung+"Hello World" einmal für die normale 
Ansteuerung und für I2C per Oszi beobachtet. Bei letzterem werden nicht 
alle Datenleitungen genutzt. Aber die PIN Zuordnungen stimmen hargenau!

Hat einer ne Anregung? Ich glaube ich bin festgefahren...

von 0undNichtig (Gast)


Lesenswert?

Hat keiner eine Idee?

von dernixwois (Gast)


Lesenswert?

Hi!
Ich geh mal davon aus, dass das Display im 4Bit Modus betrieben wird mit
einem PCF8574.

Desweiteren gehe ich davon aus das Du weißt, das man Pro zeichen oder 
Befehl erst High-byte und dan Low-Byte sendet.

Stimmt deine Adressierung des PCF8574??? Wie ist er bei dir 
Hardwaremäßig beschaltet?

Du weißt doch der PCF8574 hat eine Feste Adresse???
z.B 40h wenn alle Hardware Adressleitungen (A0,A1,A2) auf Low sind.

40h wäre hier z.B. zum schreiben und 41h zum Lesen.

SDA und SCL richtig beschaltet mit 4k7 gegen VCC??

Funktionieren bei dir die Routinen für die I²C - Bus Ansteuerungen???
INIT, STOP, Write_Byte, Read_Byte, Write_Port, Read_Port, ACK, not_ACK 
etc...
A


dernixwois

von 0undNichtig (Gast)


Lesenswert?

"und auch alle Ports können geschaltet werden"
Ja der IO funktioniert an sich einwandfrei, aber beim LCD passiert 
absolut nix.

von 0undNichtig (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal das Oszilogramm einer Init Phase. Den Anfang bis zur 4Bit Modus 
Umschaltung gehe ich ja noch mit, aber danach das kommt doch laut 
http://www.sprut.de/electronic/lcd/ nicht hin!

Hier meine Beschaltung:
LCD -> PCF
RS - P0
RW - P1
E - P2
DB4 -P3
DB5 - P4
DB6 - P5
DB7 - P6

Und so habe ich das auch in den jeweiligen Konfigurationsdateien der 
Libs geschrieben :-/

von dernixwois (Gast)


Lesenswert?

hi

Hier meine Beschaltung:
LCD -> PCF
RS - P0
RW - P1
E - P2
DB4 -P3     sollte P4
DB5 - P4    sollte P5
DB6 - P5    sollte P6
DB7 - P6    sollte P7

hier liegt der Fehler wo möglich drin: also Verdrahtung anpassen.

Du sendest ja ein nibble über den Port und wenn Du das tust dann bitte 
schön auch über  das High-nibble es Ports.

So wie es aussieht bekommt das LCD ja nur schrott.
Wenn es nicht mehr möglich ist die Verdrahtung zu verändern dann musst 
Du  über Bitschieben eine stelle nach rechts deine Routinen anpassen.

Ist aber ein bischen blöd.


Mit was für ein Tool oder Oszi hast Du dein Oszilogramm aufgenommen???

Gruß


von 0undNichtig (Gast)


Lesenswert?

Die PIN Zuordnungen kann man doch in beiden LIBs anpassen, sollte es 
damit nicht getan sein? Mich hat das schieben um 4 Stellen aber auch 
stutzig gemacht :-/

Das ist so ein Profi Oszilloskop in der Uni, hat mein Bruder für mich 
gemacht.

von 0undNichtig (Gast)


Lesenswert?

Also die Lib von COMPUTERHELD scheint Pin Neuzuordnungen garnicht 
umzusetzen, das war wohl eher wegen der verbesserten Lesbarkeit so 
aufgeschlüsselt :-(

Scriptkiller aber hat auch komisches Verhalten, ENABLE wird immer aktiv 
aber auch 2x inaktiv für eine Übermittlung geschaltet. Außerdem sind die 
Wartezeiten wohl ziemlich kurz, zumindest laut www.sprud.de :-/

Gibt es denn gar nix vernünftiges mehr???

von 0undNichtig (Gast)


Lesenswert?

Ich habe noch eine Bibliothek von Andeas Schläfer 
gefunden(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=download&id=3715), 
hier lassen sich die Pins auch nicht verändern.
Dann gibt es von Atmel auch noch die AppNote 155 aber auch die ist nicht 
so doll.

Erstaunlich wie viele Leute Zeug x mal neu schreiben und dann jedesmal 
was unterschiedliches inkompatibeles raus haben :-x

Also darf ich mir selbst eine fleur kompatible Lib schreiben :-(

von Hansi L. (fabian87)


Lesenswert?

also wenn ich das richtig verstanden habe hängt sich das Programm nicht 
beim twint check auf! Oder? wenn dus nicht weisst dann teste das mal

von 0undNichtig (Gast)


Lesenswert?

Nein, es läuft allesglatt durch.

Die Idee eine eigene Lib zu schreiben, lasse ich wohl wieder fallen, 
ohne Oszi kommt da nur Murks raus (das oben hat mein Bruder 100Km weit 
weg).

Scriptkillers Lib scheint mir noch am überschaubarsten und auch am 
fehlerfreiesten zu sein.

von dernixwois (Gast)


Lesenswert?

Hi!

>Die PIN Zuordnungen kann man doch in beiden LIBs anpassen, sollte es
>damit nicht getan sein?

Neiin!  Die logik sag einem schon das es Blödsinn ist.

>RS - P0
>RW - P1
>E - P2
>DB4 -P3
>DB5 - P4
>DB6 - P5
>DB7 - P6

Wenn Du es so verschaltest hast, kommt nur murks raus.

Das Highbyte des Lcd's auf Highbyte Port oder Lowbyte Port des PCF 8574
fest verdrahten aber nicht dazwischen.

Lies lieber mal in der Lib nach wie die Daten im 4Bit Modus am Port des
PCF8574 anliegen müssen.

von dernixwois (Gast)


Lesenswert?

Hi! nochmal!

Wie sieht den deine Hardware aus! Poste mal dein Plan.

von 0undNichtig (Gast)


Angehängte Dateien:

Lesenswert?

Sry deinen vorrigen Kommentar habe ich nciht ganz verstanden :-? Das 
Upper/Lowwer Nibble spalten und übertragen die Libs doch selbstständig 
und stellen fest, welches PIN wie verschickt werden muss.

Hier der Plan & danke schonmal für dein Engagement ;-)

von dernixwois (Gast)


Lesenswert?

Hi!

Ich glaub Du hast es noch immer nicht begriffen.

Du must dein Schaltplan ändern, da kommste nicht vorbei

von dernixwois (Gast)


Lesenswert?

In den Libs von skriptkiller und den anderen ist doch zu erkennen, das 
die das Lowbyte  an ihren Ports benutzen.

Du willst das Highbyte verwenden und ich bezweifle sehr das die Libs die 
du hast so Intelligent sind das die erkennen was da dran hängt.
Wär auch ein viel zugrosser Aufwand.

Besser! Du passt deinen Schaltplan an und machst dir eine neu Platine 
und
zwar so wie es bei den Libs beschrieben ist.

Wenn Du deine Schaltung verwenden möchtest musst Du die Lib auch 
anpassen dafür, sonst geht da gar nichts. Viel Spass dabei.


Andereseits müsstest selber Routinen schreiben zum Ansteuern des LCD's, 
I²C-Bus Treiber, LCD-Treiber

von 0undNichtig (Gast)


Lesenswert?

Sorry aber irgendwie bin ich wohl betriebsblind x-) Was meinst du?

Der PCF braucht doch wegen den anderen Pins nix umdrehen.
Das Upper/Lower Nibble ist ihm doch total egal, das interessiert doch 
nur das LCD.

Sry das ich heute so schwer von Cape bin aber nach 3 Tagen an dem 
Problem raucht mir der Kopf. Könntest du mal an einer Funktion 
beschreiben, wo es dadurch zu Problemen kommen kann?

von Michael U. (Gast)


Lesenswert?

Hallo,

die Lib von scriptkiller sollte die Definitionen richtig benutzen, ich 
habe aber nur kurz reingeschaut.

Sieht auch für ein HD44780-Controlelr ok aus.

PS: den erzeugten ASM-Code möchte ich lieber nicht sehen. ;)

Gruß aus Berlin
Michael

von 0undNichtig (Gast)


Lesenswert?

Ich bin mir nicht sicher, da SCRIPTKILLER Lib kein Busy Bit prüft.

COMPUTERHELD Lib hat wie ich oben schon sagte zwar eine Pin Neuordnung 
aber beim Lesen und zusammenführen der Nibbles gibt es IMHO Probleme.

So ein M*st, dann werde ich mich wohl doch noch selbst ransetzen 
müssen...

von dernixwois (Gast)


Angehängte Dateien:

Lesenswert?

>Das Upper/Lower Nibble ist ihm doch total egal, das interessiert doch
>nur das LCD

Eben dem LCD interessierts.

folgendes:


Z.B. um die Zahl 1 zusenden wird im 4 bit Modus  erst das Highbyte und 
dann das Lowbye gesendet und das LCD macht daraus wieder ein ganzes Byte 
um es intern weiter zuverarbeiten.

Im Anhang siehst Du ein Beispiel wie ich es mal Angeschlossen habe.

Darauf habe ich meinen Code Aufgebaut. wenn ich nun die Zuweisungen in 
der Software um 180 Grad verändere passt nichts mehr zusammen und müsste 
meinen Code anpassen.

Bsp.  Port 1 ist LCD Port

sfr ausg_lcd=0x90; Port 1

Um den Cursor auf Zeile 1 zu bringen habe ich wie folgt gemacht

Der Befehl dazu für LCD ist 0x80  oder 80h

void switch_z1(void)
{
 ausg_lcd=0x08;      // HIGH-BYTE Senden
 lcd_com();          // Enable Sequenz
 ausg_lcd =0x00;     // LOW-BYTE Senden
 lcd_com();          // Enable Sequenz

}

Wenn ich nun mein LCD auf dem Highbyte des Port's1 (P4-P7)angschlossen 
hätte müsste das dan so aussehen.

void switch_z1(void)
{
 ausg_lcd=0x80;      // HIGH-BYTE Senden
 lcd_com();          // Enable Sequenz
 ausg_lcd =0x00;     // LOW-BYTE Senden
 lcd_com();          // Enable Sequenz

}

Fazit: Deine Hardware passt nicht zu deiner Software deshalb sagte ich 
doch
ändere deinen Schaltplan so das Du mit den Libs arbeiten kannst.

Anschluss deines LCD's DB4-DB7)an den PCF8574 an P3-P6 ist falsch.
Richtig wäre P4-P7 aber besser für dich und Libs P0-P3





von dernixwois (Gast)


Lesenswert?

Nochmal anders!

Bei Skriptkiller wird das untere Halbyte für die Datenübertragung 
verwendet und das Obere zum Steuern.

P1   <->    LCD
 ----------------------------------------------
 P0    <->    DB4
 P1    <->    DB5
 P2    <->    DB6
 P3    <->    DB7
 P4    <->    RS
 P5    <->    R/W
 P6    <->    -
 P7    <->    Enable

0x80 zu übertragen muss volgendes am Port anliegen

10001000b     Erst Higbyte senden von 0x80  also 8
   .
   .
00001000b    mit Fallender Flanke übernimt LCD das lowbyte vom Port1

10000000b    dann Lowbyte senden von 0x80 also 0
    .
    .
00000000b    mit Fallender Flanke übernimt LCD das lowbyte vom Port1

Zeichen 0x80 wurde übertragen.

von Michael U. (Gast)


Lesenswert?

Hallo

aus der Lib von scriptkiller:

lcd.h
/* pin definitions */

#define P0 0x01
#define P1 0x02
#define P2 0x04
#define P3 0x08
#define P4 0x10
#define P5 0x20
#define P6 0x40
#define P7 0x80

...

#define LCD_D4 P7
#define LCD_D5 P6
#define LCD_D6 P5
#define LCD_D7 P4

#define LCD_RS P1
#define LCD_RW P2
#define LCD_E  P3

aus lcd.c

void lcd4BitOut(unsigned char c, unsigned char data) {

  unsigned char out;
  unsigned char rs;


  rs=0;
  if(data)
    rs=LCD_RS;

  /* 4 upper bits */
  out=0;
  if(c & 0x80) out |= LCD_D7;
  if(c & 0x40) out |= LCD_D6;
  if(c & 0x20) out |= LCD_D5;
  if(c & 0x10) out |= LCD_D4;
  lcdOut(out | rs);
  //  lcd_usleep(1);
  lcdOut(out | rs | LCD_E);
  lcd_usleep(1);
  lcdOut(out | rs);

  /* 4 lower bits */
  out=0;
  if(c & 0x08) out |= LCD_D7;
  if(c & 0x04) out |= LCD_D6;
  if(c & 0x02) out |= LCD_D5;
  if(c & 0x01) out |= LCD_D4;
  lcdOut(out | rs);
  //  lcd_usleep(1);
  lcdOut(out | rs | LCD_E);
  lcd_usleep(1);
  lcdOut(out | rs);


}

Das Ausgabebyte wird genau aus der Definition zusammngebastelt, es ist 
also egal, wie die Leitungen beschaltet werden, wenn nur die Zuweisungen 
stimmen...

Man möge mich korrigieren, ich habe mit C nichts am Hut. ;)

Gruß aus Berlin
Michael


von 0undNichtig (Gast)


Lesenswert?

Ebend, so langsam hatte ich selbst nicht mehr durchgesehen^^

Prinzipiell hat dernixwois natürlich recht. Das hatte ich total 
vernachlässigt, das wäre mir eher aufgefallen, wenn die Pins kreuz und 
quer gelegen hätten und nicht so in einem Nibble Block.

Dann muss man es natürlich so machen, wie ScriptKiller, der das ganze 
auf Bit-Ebene auseinanderdruselt. Leider scheint die fehlende BUSY Flag 
Abfrage aber dort das Krux zu sein.

Habe inzwischen eine eigene Lib angefangen und da ist mri das Problem 
natürlich deutlich ins Auge gestochen. Werde mich morgen nochmal ran 
machen, und die Bits verrücken. Platine neu machen ist definitiv nicht 
drinne ;-)


Danke nochmal Leute! Manchmal sieht man die 1en vor lauter 0en nicht :-)

von Michael U. (Gast)


Lesenswert?

Hallo,

Busy-Flag ist eigentlich nicht das Problem. Die Wartezeiten müssen eben 
nur sicher lang genug sein.
Zu lang stört eigentlich nur den Programmablauf. ;)

Das ist aber in der scriptkiller-Lib auch nur eine Routine, die man 
erstmal anpassen könnte:

lcd.c

void lcd_usleep(unsigned int msec) {

  /* 16-bit count, 4 cycles/loop */
  _delay_loop_2(1000*msec);

}

Dazu kann ich dann mangels C-Nutzung erstmal nichts sagen...

Gruß aus Berlin
Michael

von 0undNichtig (Gast)


Lesenswert?

Ja ich habe es mit SCRIPTKILLERS Lib hingekriegt.
Das Timing musste aber ganz schön angepasst werden:
_delay_loop_2(2000*msec);
Und die auskommentierte Verzögerung in lcd_send_4bit musste reaktiviert 
werden.

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.