Forum: Mikrocontroller und Digitale Elektronik Standart LCD per i2c expander betreiben


von mr. mo (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
bin faul geworden und hatte keine Lust mehr immer so viel aufm 
Steckbrett zu stecken, also kam mir die Idee das LCD einfach per Port 
Expander (PCF8574) zu betreiben.
Habe also meine alte lcd.h genommen und auf i2c umgebaut. Klappte alles 
soweit Prima, Variablen und sowas lassen sich ausgeben. Problem liegt 
nun aber in der Initialsisierung. Das Display wird nicht mehr zwei 
Zeilig initialisiert. Habe schon die Zeiten geändert und rumgefummelt, 
es will aber dennoch nicht so richtig.

Meine Vermutung ist irgendwie das irgendwas mit den Timings nicht 
stimmt. Die Initialisierung ist aber vom Aufbau her genau (bis natürlich 
auf die Abänderung auf i2c) die gleiche die ich vorher auch immer 
benutzt habe.

Im Anhang habe ich mal die Libraries für den PCF8574 und das LCD.
Die i2c Library ist das gute Stück vom Peter F.
Display ist das 4 zeilige von Pollin ( 
http://www.pollin.de/shop/dt/MTczOTc4OTk-/Bauelemente_Bauteile/Aktive_Bauelemente/Displays/LCD_Modul_TC1604A_01.html 
)
1
// Defines
2
#define F_CPU 16000000UL
3
4
// Libraries
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <util/twi.h>
8
9
#include "i2c.h"
10
#include "PCF8574.h"
11
#include "i2c_lcd.h"
12
13
  
14
int main(void){
15
  i2c_ini();
16
  lcd_ini();
17
18
    
19
  lcd_string_xy(5,1,"text1");
20
  lcd_string_xy(5,2,"text2");
21
  lcd_string_xy(5,3,"text3");
22
  lcd_string_xy(5,4,"text4");  
23
  
24
  i2c_stop();
25
  
26
  return 0;
27
}

von mr. mo (Gast)


Lesenswert?

Hab vergessen zu erwähnen:
Ist ein Atmega16 mit externen 16MHz Quarz. Der i2c läuft mit 400kHz.
Ändern der i2c Frequenz hatte auch nichts geändert.

von mr. mo (Gast)


Lesenswert?

Sorry, aber: BUMP

von mr. mo (Gast)


Lesenswert?

So wie ich sehe haben sich immerhin ein paar Leute das Problem 
angesehen.

Fehlt denn vielleicht noch irgendwas an Informationen? Oder ist etwas 
nicht verständlich erklärt? Ich wäre auch bereit einzelne Teile zu 
erklären, falls nicht erkenntlich ist was ich mir da gedacht habe.

von Carsten W. (eagle38106)


Angehängte Dateien:

Lesenswert?

Ich würde mal die Datenleitungen DB0.. 3 nicht nach Masse kurzschließen.

Zum korrekten Initialisieren siehe Datenblatt des HD44780:

[Zitat]
Instruction and Display Correspondence

·  8-bit operation, 8-digit x 1-line display with internal reset

Refer to Table 11 for an example of an 8-digit x 1-line display in 8-bit 
operation. The HD44780U functions must be set by the function set 
instruction prior to the display. Since the display data RAM
can store data for 80 characters, as explained before, the RAM can be 
used for displays such as for advertising when combined with the display 
shift operation.
Since the display shift operation changes only the display position with 
DDRAM contents unchanged, the first display data entered into DDRAM can 
be output when the return home operation is performed.

·  4-bit operation, 8-digit x 1-line display with internal reset

The program must set all functions prior to the 4-bit operation (Table 
12). When the power is turned on, 8-bit operation is automatically 
selected and the first write is performed as an 8-bit operation. Since 
DB0 to DB3 are not connected, a rewrite is then required. However, since 
one operation is completed in two accesses for 4-bit operation, a 
rewrite is needed to set the functions (see Table 12).
Thus, DB4 to DB7 of the function set instruction is written twice.

·  8-bit operation, 8-digit x 2-line display

For a 2-line display, the cursor automatically moves from the first to 
the second line after the 40th digit of the first line has been written. 
Thus, if there are only 8 characters in the first line, the DDRAM 
address must be again set after the 8th character is completed. (See 
Table 13.) Note that the display shift operation is performed for the 
first and second lines. In the example of Table 13, the display shift is 
performed when the cursor is on the second line. However, if the shift 
operation is performed when the cursor is on the first line, both the 
first and second lines move together. If the shift is repeated, the 
display of the second line will not move to the first line. The same 
display will only shift within its own line for the number of times the 
shift is repeated.

Note: When using the internal reset, the electrical characteristics in 
the Power Supply Conditions Using Internal Reset Circuit table must be 
satisfied. If not, the HD44780U must be initialized by instructions. See 
the section, Initializing by Instruction.
[/Zitat]

Ach, und bitte keinen Code in Header-Dateien.

Gruß
Carsten

von mr. mo (Gast)


Lesenswert?

Carsten Wille schrieb:
> Ich würde mal die Datenleitungen DB0.. 3 nicht nach Masse kurzschließen.
Warum das?

> Ach, und bitte keinen Code in Header-Dateien.
Zum dran rumbauen geht das klar ^^


Das Problem ist ja, dass die ursprüngliche Form der Initialisierung 
super funktioniert hat. Alle HD44780 Displays (oder komp. sind) die ich 
hier rumfliegen habe funktionieren damit ohne Probleme.

von spess53 (Gast)


Lesenswert?

Hi

>Warum das?

Weil die Displaycontroller interne Pull-Up-Widerstände haben. Also 
entweder offen lassen oder wenn es Probleme gibt an VCC.

MfG Spess

von mr. mo (Gast)


Lesenswert?

Pins an VCC, offen und Pins untereinander verbunden und Pins ohne alles 
bringt leider kein anderes ergebnis. Meine Textstücke sind immer noch in 
der 1. und 3. Zeile verteilt.

von Oliver J. (skriptkiddy)


Lesenswert?

mr. mo schrieb:
> Pins an VCC, offen und Pins untereinander verbunden und Pins ohne alles
> bringt leider kein anderes ergebnis. Meine Textstücke sind immer noch in
> der 1. und 3. Zeile verteilt.

Wie sieht die Ausgabe genau aus? Mach mal ein Foto.

Stimmen denn die Offsets?
#define lcd_ddram       0x80  // 1. row
#define lcd_ddram_2     0x40  // 2. row
#define lcd_ddram_3     0x10  // 3. row
#define lcd_ddram_4     0x50  // 4. row

von spess53 (Gast)


Lesenswert?

Hi

>Pins an VCC, offen und Pins untereinander verbunden und Pins ohne alles
>bringt leider kein anderes ergebnis.

Hat auch niemand behauptet, das das die Ursache für die Fehlfunktion 
deines Displays ist. Es ging mehr darum diesen weit verbreiteten 
Blödsinn klar zu stellen.

MfG Spess

von mr. mo (Gast)


Lesenswert?

Skript Kiddy schrieb:
> Wie sieht die Ausgabe genau aus? Mach mal ein Foto.

Habe die Ausgabe einfach mal wie folgt abgeändert:
1
        lcd_string_xy(1,1,"1");
2
  lcd_string_xy(1,2,"2");
3
  lcd_string_xy(1,3,"3");
4
  lcd_string_xy(1,4,"4");

Ausgabe ist an der Stelle schonmal eindeutig.
1.Zeile: 4
2.Zeile:
3.Zeile: 3
4.Zeile:

Ich habe langsam die Vermutung das meine lcd_command(); Funktion nicht 
richtig arbeitet. Die lcd_data(); scheinbar schon. Denn wenn ich 
testweise die Funktion z.B. lcd_command(display_off); einbaue passiert 
gar nichts.

spess53 schrieb:
>Es ging mehr darum diesen weit verbreiteten
> Blödsinn klar zu stellen.

Ist leider wahr, was man sieht prägt man sich ein. Hinterfragt hab ich 
das auch nicht. Habe mir diese Belegung von langer Zeit bei meinem myAVR 
Board abgeguckt.

von Falk B. (falk)


Lesenswert?

@  mr. mo (Gast)

>Ich habe langsam die Vermutung das meine lcd_command(); Funktion nicht
>richtig arbeitet. Die lcd_data(); scheinbar schon.

Dazu sollte man VOLLSTÄNDIGEN COde als Anhang posten. Deine PCF 
Funktionen fehlen.

MFG
Falk

von mr. mo (Gast)


Lesenswert?

Falk Brunner schrieb:
> @  mr. mo (Gast)
>
>>Ich habe langsam die Vermutung das meine lcd_command(); Funktion nicht
>>richtig arbeitet. Die lcd_data(); scheinbar schon.
>
> Dazu sollte man VOLLSTÄNDIGEN COde als Anhang posten. Deine PCF
> Funktionen fehlen.
>
> MFG
> Falk

Sind in der PCF8574.h

von Oliver J. (skriptkiddy)


Lesenswert?

> Habe die Ausgabe einfach mal wie folgt abgeändert: 
lcd_string_xy(1,1,"1");
>   lcd_string_xy(1,2,"2");
>   lcd_string_xy(1,3,"3");
>   lcd_string_xy(1,4,"4");
>
> Ausgabe ist an der Stelle schonmal eindeutig.
> 1.Zeile: 4
> 2.Zeile:
> 3.Zeile: 3
> 4.Zeile:


Dann liegt schonmal die 1. Zeile an 0x50, würde ich sagen.

Daraus folgt:

#define lcd_ddram       0x50  // 1. row
#define lcd_ddram_2     0x??  // 2. row
#define lcd_ddram_3     0x10  // 3. row
#define lcd_ddram_4     0x??  // 4. row

von mr. mo (Gast)


Lesenswert?

Skript Kiddy schrieb:
> Dann liegt schonmal die 1. Zeile an 0x50, würde ich sagen.
>
> Daraus folgt:
>
> #define lcd_ddram       0x50  // 1. row
> #define lcd_ddram_2     0x??  // 2. row
> #define lcd_ddram_3     0x10  // 3. row
> #define lcd_ddram_4     0x??  // 4. row

Ok. Ich muss aber noch dazu sagen, dass ich dieses Display erfolgreich 
so angesteuert habe. Bevor ich das auf den Expander gepackt habe war es 
direkt am ATmega16 angeschlossen.

Der alte code war:
1
// Cursor Position setzen
2
void lcd_cursor(uint8_t zeile, uint8_t spalte) {
3
    // 1.Zeile
4
    if(zeile == 1) {
5
        lcd_command(lcd_ddram + (spalte-1));
6
    }
7
    // 2.Zeile
8
    if(zeile == 2) {
9
        lcd_command(lcd_ddram + lcd_ddram_2 + (spalte-1));
10
    }
11
    // 3.Zeile
12
    if(zeile == 3) {
13
        lcd_command(lcd_ddram + lcd_ddram_3 + (spalte-1));
14
    }
15
    // 4.Zeile
16
    if(zeile == 4) {
17
        lcd_command(lcd_ddram + lcd_ddram_4 + (spalte-1));
18
    }
19
}

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Die LED-Hintergrundbeleuchtung darf man bei den meisten Modulen NICHT 
ohne Vorwiderstand an VCC anschließen. Wenn du WIRKLICH die 
LED-Beleuchtung schalten willst, mach es wie im Anhang. Aber ein 
Transistor und zwei Widerstände braucht es schon.

In der Software sehe ich keinen Bug, vielleicht hast du einen 
Verdrahtungsfehler, Kurschluss, Wackelkontakt.

MfG
Falk

von mr. mo (Gast)


Lesenswert?

Falk Brunner schrieb:
> Die LED-Hintergrundbeleuchtung darf man bei den meisten Modulen NICHT
> ohne Vorwiderstand an VCC anschließen. Wenn du WIRKLICH die
> LED-Beleuchtung schalten willst, mach es wie im Anhang. Aber ein
> Transistor und zwei Widerstände braucht es schon.

Der Zusatz mit dem Hintergrundbeleuchtung schalten ist mir beim 
zusammenlöten eingefallen. Deshalb ist das in dem Schaltplan nicht drin.

> In der Software sehe ich keinen Bug, vielleicht hast du einen
> Verdrahtungsfehler, Kurschluss, Wackelkontakt.

Hmm.

Ich verstehe nur noch nicht, warum funktioniert die lcd_data(); Funktion 
und die lcd_command(); nicht.
Die Datenpins falsch angelötet haben kann ich ja eigentlich auch 
nicht, weil wenn ich ganze Wörter ausgeben will sind diese auch richtig 
dargestellt?!

Ich glaube ich werde morgen mal hingehen und die Initialisierung 
komplett von Hand machen und jedes Byte einzeln schicken. Wenn das 
funktioniert muss der Fehler irgendwo in der Logik hängen und hat sich 
sehr gut versteckt.

Bis dahin schonmal vielen dank an euch, dass ihr euch mein Codechaos 
angeschaut habt.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Der PCF8574 ist nur für 100KHz gedacht. Also das erstmal ändern.

Dann immerschön längere Zeit warten nach dem Senden eines Bytes an das 
LCD.

von Tip (Gast)


Lesenswert?

mr. mo schrieb:
> Pins an VCC, offen und Pins untereinander verbunden und Pins ohne alles
> bringt leider kein anderes ergebnis. Meine Textstücke sind immer noch in
> der 1. und 3. Zeile verteilt.

Wie soll das auch was ändern.
Das bezog sich auf die Anmerkung im Datenblatt, wo zu DB0..DB3 steht 
"These pins are not used during 4-bit operation."

von mr. mo (Gast)


Lesenswert?

Habe folgende änderungen gemacht:
1. die i2c Frequenz auf 100kHz gestellt.
2. die unbenutzen Datenpins des LCDs in der Luft hängen lassen.
2. die lcd_reset_c Zeit von 101us auf 200us erhöt.

Nun funktioniert es!!!
Obwohl ich noch sagen muss, dass der Port Expander sogar mit 400kHz 
sauber überträgt.

Nun hab ich aber noch eine Frage. Meine Zeichen werden ordentlich 
dargestellt, wenn ich aber den Reset des ATmega16 betätige kommt es 
manchmal vor, dass mir das Display Schrott anzeigt, also die Zeichen 
sind dann komplett durcheinander.
Woher kommt das? Sollte das Display nicht durch die Inititalisierung 
einmal geleert werden und dann die neu gesendeten Zeichen empfangen?

von mr. mo (Gast)


Lesenswert?

Ok das mit dem Reset zieh ich zurück. Das verursacht mein 
Programmiergerät. Sollange dies nicht angeschlossen ist wird alles 
richtig gemacht.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Vermutlich stimmt irgendwas mit 4Bit/8Bit Umschaltung nicht. Da gibts so 
ne längliche Sequenz, um auf jeden Fall den Controller in den 4Bit Mode 
zu bringen. Datenblatt schauen. Es sind auch nicht alle Controller 
gleich!

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.