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?
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.
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?
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.
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.
@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
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.
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
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.
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.
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
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.
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.
....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....
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.
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.
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
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.
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
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.
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
voidlcd_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
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);
}