www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Display (HD4478099) zeigt nur Kästchen


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo leute!
Ich habe gerade versucht ein LCD Display (das normale HD44780) an
meinen AVR anzuschlißen. Leider bin ich aus dem Tutorial hier nicht
ganz schlau geworden, da es in Assembler geschrieben ist (ich nehm
GCC). Ich hab trotzdem versucht das so gut wie möglich zu übersetzen.
Leider wird auf dem Display nichts angezeigt, ich sehe nur 8 Schwarze
Kästchen. Hier mein code:

Ich habe diese beiden Funktionen, die ich nacheinander aufrufe:


void setModeData( void )
{
  PORTC |= (1<<PC1);
}

void writeByte( void )
{
  //PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5);

  unsigned char i=0;
  while(i<150) {i++;};


  PORTC |= (1<<PC3)|(1<<PC5);

  PORTC |= (1<<PC0);
  i=0;
  while(i<150) {i++;};
  PORTC &= ~(1<<PC0);

  PORTC &= ~(1<<PC3);
  PORTC &= ~(1<<PC5);

  PORTC |= (1<<PC4);

  PORTC |= (1<<PC0);
  i=0;
  while(i<150) {i++;};
  PORTC &= ~(1<<PC0);
}

Hat jemand eine Idee, warum da kein Zeichen ausgegeben wird?
Danke!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du das Display initialisiert???

Autor: Asterix-007 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

das sieht mir ganz nach zuviel Kontrast aus!

Also prüfe ob du die Kontrastspannung angeschlossen hast(Pin 3 am
Display)! Wenn ja drehe am Regler und schau ob sich etwas tut. Bis
hierhin brauchst du noch keine Daten zum Display senden.

Im Normalfall solltest du jetzt die Kästchen abschwächen können, bzw.
sie ganz verschwinden lassen. Beachte, wenn du zu wenig Kontrast gibst,
siehst du keine Zeichen mehr!!!!!

Ich stelle den Kontrast zum Test bei mir immer so ein, dass ich die
Segmente immer noch leicht sehen kann. Wenn alles funktioniert kannst
du dann nach deinem Gutdünken verfahren.

mfg

Asterix-007

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Hast Du das Display initialisiert???"
Muss man das? Wie geht denn das? Reicht es da ein paar Bytes zu senden,
und wenn ja welche???
Danke :-)

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Muss man das? Wie geht denn das? Reicht es da ein paar Bytes zu senden,
und wenn ja welche???

naja, man braucht eine kleine Sequenz, die aber im Datenblatt meist
beschrieben ist...

Autor: xXx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso?
Für was braucht man ein Datenblatt lesen. Außerdem ist das auch noch
auf Englisch!!!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im org. Datenblatt setht die Init Sequenz als Tabelle drin.
muß man nur abtippen !!!!
ist doch nicht sooo schwer.
Dafür kommt man ja schon fast ohne english aus..

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das datenblatt hat immerhin 60 Seiten ;-)
Ich hab versucht die Initialisierung zu implementieren, aber ich
versteh sie ehrlich gesagt nicht so ganz. Das ist irgendwie ziemlich
blöd aufgeschrieben...

Das habe ich bis jetzt (von Seite 46):

void initDisplay( void )
{
  // Belegung am Port C:
  //      E RS DB4 DB5 DB6 DB7 ?  ?
  // 0 b  0 0  0   0   0   0   0  0


  WaitMs(20);  // Warte erstmal 20 ms

  PORTC = 0b00110000;  // Setze DB4 und DB5 auf 1

  WaitMs(10);  // Warte nochmal 10 ms

  PORTC = 0b00110000;  // Nochmal: Setze DB4 und DB5 auf 1

  WaitMs(10);  // Warte diesmal 2 ms

  PORTC = 0b00110000;  // Zum 3. mal: Setze DB4 und DB5 auf 1
}

Warum muss ich denn immer wieder den selben Code senden?
Und dann stehen auf der Seite in den nachfolgenden Codes noch *, ein N,
ein F und sowas.... HÄ???

Danke für eure Hilfe :-)

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
am besten nimmst du die lib von peter fleury.
mit der geht das dann recht einfach.

gruß michael

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich hatte ich gehofft das nicht tun zu müssen. Die Lib ist mir
nämlich etwas zu komplex (OK, dafür auch flexibel) ;-)
Aber ich will mit dem Display ja garnicht viel machen: Nur einmal
initialisieren, und dann von Zeit zu Zeit mal nen String ausgeben...
Ich hatte irgendwie gehofft das wäre leicht machbar :-(
Das kann doch nicht so schwer sein!?!?!

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja ist doch fast geschafft.
Diese Werte benutze ich für 4Bit.

tabelle_init:  DB  30h,30h,30h,20h,28h,08h,01h,06h,0fh

So jetzt leg los.

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ansosnten schau Dir meine Routine an. LCD Ansteuerung in ISR auf 8051.
Da mußt Du nur den RAM beschreiben. Der Rest geht fast von alleine.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, danke Stefan :-)
Werd's bald testen... Wo finde ich denn deine Routine?

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
suche nach Displayansteuerung in ISR oder nimm die 3fach Strom
Spannungsanzeige.
Bei Displayansteuerung sind noch Beiträge von Pieter und Peter drin.
Vieleicht helfen die Codes weiter.
Gibt wirklich genug hier davon und bei google noch ewige Meter Seiten
mehr.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, nachdem ich jetzt ales fleißig gelsen habe, habe ich folgende Init
Funktion gebastelt:

PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00010000;
WaitMs(10);
  PORTC = 0b00010000;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00000100;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00100000;
WaitMs(10);
  PORTC = 0b00111000;
WaitMs(10);

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, nachdem ich nun alles fleißig gelsen habe bin ich zu folgender Init
Funktion gelangt:

WaitMs(20);
  PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00110000;
WaitMs(10);
  PORTC = 0b00010000;
WaitMs(10);
  PORTC = 0b00010000;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00000100;
WaitMs(10);
  PORTC = 0b00000000;
WaitMs(10);
  PORTC = 0b00100000;
WaitMs(10);
  PORTC = 0b00111000;
WaitMs(10);

Es tut sich aber leider garnichts :-(

Hier nochmal die Pinbelegung:

// Pin connections:
//  - PC0 - Grün    = E
//  - PC1 - Gelb    = RS
//  - PC2 - Orange    = DB4
//  - PC3 - Rot      = DB5
//  - PC4 - Braun    = DB6
//  - PC5 - Schwarz    = DB7

Oder:

  // Belegung am Port C:
  //      E RS DB4 DB5 DB6 DB7 ?  ?
  // 0 b  0 0  0   0   0   0   0  0

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huh, wo kommt der erste doppelpost her? Kann ich den nicht irgendwie
löschen???

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Beitrag melden"...(rechts im orangen Kasten)

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist PC0 ???? D0 an Port C ????? mit Wertigkeit von 2 hoch 0 =1 ??

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das musste schon umdrehen, sonst klappt gar nix. Außerdem setzt Du das
Enable nie, so dass überhaupt nix übertragen werden kann. Vielleicht
solltest Du Dir tatsächlich mal ein paar Abschnitte im Datenblatt
ansehen. Und natürlich Grundlagen Zahlendarstellung (Hex und Binär)...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Info: PC0 ist das niedrigstwertige (oder nierderwertigste...???) Bit
in PORTC. Das steht in der Binärdarstellung ganz rechts. Ist genau wie
im Dezimalsystem (da stehen die niederwertigen Stellen auch rechts),
nur dass hier die Basis 2 ist.

Dezimal: z.B.
...1000er, 100er, 10er, 1er

Binär:
...128er, 64er, 32er, 16er, 8er, 4er, 2er, 1er
(0b  0     0     0     0     0    0    0    0)

Solange Du das nicht verstanden hast, brauchst Du mit µC-Programmierung
gar nicht erst anzufangen. Bitte beschäftige Dich zunächst mit den
Grundlagen. Aber lass Dich nicht entmutigen. Es ist noch kein Meister
vom Himmel gefallen. Alles Schritt für Schritt...

Gruß

Johnny

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Es ist noch kein Meister vom Himmel gefallen.
Wenn einer nach bestandener Meisterprüfung einen Tandem-Sprung
geschenkt bekommen hat, schon... ;)

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und bitte,.....

D4-D7 vom Display bitte auf PC0-PC3 oder PC4-PC7.
ABER nicht unbedingt in die Mitte. Du machst Dir das Leben nur unnötig
schwer damit. ( Swappen )

Hab ichs doch richtig gesehen.....
Die Aufstellung Deiner Binärzahlen ist ja völlig falsch !!!!

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schau mal auf www.sprut.de nach.
da wird dann einiges klar.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> OK, nachdem ich nun alles fleißig gelsen habe bin ich zu
> folgender Init Funktion gelangt:
>
> WaitMs(20);
>   PORTC = 0b00110000;
> WaitMs(10);
>   PORTC = 0b00110000

WaitMs() wartet nur, richtig?

Also, dann wird das so nichts. Einfach nur am PortC irgendwelche
Daten anlegen ist zuwenig. Dadurch wird nichts uebertragen.
Du musst schon an den anderen Pins (Enable, Write) am LCD
auch noch wackeln.

Studier doch mal den Source Code von Peter Fleury, auch wenn
sie dir jetzt komplex erscheint, was sie in Wirklichkeit
nicht ist). Geh in Gedanken die Init-Sequenz dort durch
und schau nach was er anders macht. Du kannst dadurch nur lernen.
Es hilft auch das ganze mal im AVR-Studio im Debugger durchzusteppen
und die Port-Ausgänge zu beobachten. Auch da sieht mann sehr schön
welche Pins in welcher Reihenfolge auf 1 bzw. 0 gehen müssen.
Zumindest in der Init-Sequenz.

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl Heinz,
der Michael hat grundlegende Probleme.
Schau Dir mal die Beschaltung an.
E ist in der Pinbelegung angeblich auf PC0 in seiner Binärzahl aber auf
Bit 7 !!!! Sooo wird das nie was.
Da sind die Steuersignale nur noch das I-Tüpfelchen.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl Heinz hat aber im Prinzip recht: Wenn Michael erst mal die
Zahlensysteme verstanden hat und sich noch ein paar weitere Grundlagen
angeeignet hat, dann sollte er sich vielleicht wirklich mal fertigen
Code ansehen und versuchen, den zu verstehen. Die fehlenden Grundlagen
sind sicher auch der Hauptgrund für seine Aussage, dass ihm die Lib von
Peter Fleury zu komplex ist. Klar, wenn ich grad dabei bin, zu lernen,
dass 1 + 1 = 2 ist, dann ist ein Dreisatz für mich auch komplex...

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>1 + 1 = 2
Das ist aber eher ein Problem der Definition des Zeichensatzes / der
Syntax (oder war es die Semantik?)...
1 + 1 könnte auch 10 oder 1 sein...
Grundlagen haben noch niemandem geschadet...

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und noch verrückter vird es digital, da ist 1+1=0 und C=1

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
digital ist ein Plus ein ODER !!!! ALso 1+1=1 !!

Autor: Chris V (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
digital ist ein Plus ein XOR !!!! Also 1+1=0 !!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan: nicht unbedingt...
in der "deutschen" Digitaltechnik wird das "Oder" auch als "v"
(vom lateinischen vel = oder) dargestellt. Das "Und" als ^, wobei es
sich bei beiden Symbolen um richtige (kleine) Dreiecke handelt. Man
kann es sich auch so merken: "Oder" ist ist oben offen und "Und"
unten...
"+" und "*" kommen aus dem angloamerikanischen Sprachgebrauch,
wobei das "+" noch einen Kreis drumherum haben müsste...

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<digital ist ein Plus ein ODER !!!! ALso 1+1=1 !!
Nicht ganz, weil es ist Sprachenabhängig. Wenn ich es matematisch
betrachte ist die Addition gemeint. Betrache ich es aus der Richtung
Schaltalgebra stimmt das.
Verrückte Welt!
MFG Uwe

Autor: Chris V (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan: Wenn du das "+" als Verknüpfungsoperator gemeint hast, gebe
ich mich geschlagen. Wenn ich aber eine Addition ausführen möchte
verlasse ich mich doch lieber auf das XOR wo 1+1 0 ergibt(plus den
natürlich fälligen Übertrag).

Gruß Chris

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
beim XOR-Plus war der Kreis drum...war wohl etwas falsch in der
Erinnerung...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sch**** da hab ich ja was losgetreten... Sollte doch nur ein Beispiel
aus dem wahren Leben sein... und da lernt man zuerst mal normalerweise
Dezimalsystem... Bei mir wars jedenfalls so. Fest steht, dass der
Ausdruck 1+1=2 in jedem gebräuchlichen Zahlensystem, in dessen
Zahlzeichenvorrat es eine 2 gibt, korrekt ist. Das kann man jetzt
wahrscheinlich auch noch tausendmal drehen und wenden...

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, vielen Dank erstmal für euren Input :-) Ich habe mich mittlwerweile
ein wenig schlau gemacht, was die Binärzahlen angeht. Mein größtes
Problem war wohl, dass ich dachte die Bits an den AVR-Ports wären 0 bis
7 aufsteigend. Aber wenn ich das jetzt richtig verstanden habe siehts so
aus:

PORTC = 0b76543210;

(Wobei die Zahlen jetzt nur für die Pins stehen, nicht für Bits!). Ist
das korrekt so?


Dann nochmal zum Display: ich habe leichte Probleme mit der
Sprut.de-Tabelle (Hier der Link direkt darauf:
http://www.vankurt.de/images/dispTab.gif)

Zu den ersten drei Befehlen hab ich diesen Init-Code gebastelt:

WaitMs(20);        // Warte erstmal 20 ms
  PORTC = 0b00001101;    // Setze ENABLE, DB4 und DB5 auf 1  (8-Bit 
Modus)
  WaitMs(10);        // Warte 10 ms
  PORTC = 0b00001101;    // Setze ENABLE, DB4 und DB5 auf 1  (8-Bit 
Modus)
  WaitMs(5);        // Warte 5 ms
  PORTC = 0b00001101;    // Setze ENABLE, DB4 und DB5 auf 1  (8-Bit 
Modus)
  WaitMs(5);        // Warte 5 ms
  PORTC = 0b00001001;    // Setze ENABLE, DB4 und DB5 auf 1  (4-Bit 
Modus)

Ist der denn so weit in Ordnung?

Mein Problem ist dann der letze Teil der Tabelle. Sollen das da einfach
10 Befehle sein? Weil zuerst wurden die ja einzelnd tabellenmäßig
getrennt, jetzt stehen sie direkt untereinander....
Und warum sind da Variablen wie N(1) oder F(0) drin? Und was bedeurten
dann die "-" ? Soll man die auf 1 oder 0 setzen? Und wofür stehen die
verschiedenen Hintergrundfarben (gelb, grün, blau)???? Sehr verwirrend
das ganze!! :-(

Ich hoffe ihr helft nochmal :-D

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie ist denn das Display jetzt wirklich angeschlossen ?? Das müssen wir
schon wissen.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh :-)
Also eigentlich wie gehabt, nur halt andersrum:

// Belegung am Port C:
//      ? ?  DB7 DB6 DB5 DB4 RS E
// 0 b  0 0  0   0   0   0   0  0

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
30h,30h,30h,20h,28h,08h,01h,06h,0fh
das sind die werte, so nun mal sehen,

30h   b00001100
20h   b00001000
28h   b0010000 und danach b00001000  erst high dann low

und so weiter, die Signale von RS E und RW kommand dann noch dazu.
Sind jetzt nicht berücksichtigt !!!!
ABER wie ich sagte mache die Belegung anders. Du machst Dir nen Wolf
mit dem Nibbeln der Bytes.

Folgender Vorschlag:
       0b 0  0   0    0   0   0   0   0    Bits binär
             E  RS   RW  DB7 DB6 DB5 DB4   Display
            PC6 PC5  PC4 PC3 PC2 PC1 PC0   Port C

Dann siehst so aus:

30h    0b    x  x  x  0   0   1   1

die X Werte müssen entsprechend gesetzt werden. Je nachdem ob Du
lesen/schreiben willst, Befehle oder Daten sendest.

Ab der 28h wird alles in 2er Paketen geschrieben. Erst High Nibble dann
Low Nibble. Die 28h  wäre dann 0b0000 0010 und 0b0000 1000.
Das Leerzeichen ist nur symbolisch zum besseren Verständnis für Dich.

So mehr kann man jetzt wirklich nicht für Dich tun.

Habe fertig.

stephan

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>30h   b00001100
>20h   b00001000

sollte 30h nicht eher b00110000 und 20h b00100000 heissen?
Deine Schreibweise gilt wohl eher als die Bit-Reihenfolge bei der
Übertragung über die serielle Schnittstelle...

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rahul,
er hat an Bit 0 und 1 RS und E !!!
Das wirkliche Bit 0 ist an Bit 2 !!!
Jetzt kalr ??? Deswegen sagte ich ja er soll umstrippen.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal, dass du dir so viel Mühe gibst, Stefan :-)
Leider hab ich's immer noch nicht hinbekommen...
Damit das klar ist:

"30h,30h,30h,20h,28h,08h,01h,06h,0fh
das sind die werte, so nun mal sehen,"

Für welche Pin-belegung sind die denn gedacht? Die aus deinem
Vorschlag?

"Folgender Vorschlag:
       0b 0  0   0    0   0   0   0   0    Bits binär
             E  RS   RW  DB7 DB6 DB5 DB4   Display
            PC6 PC5  PC4 PC3 PC2 PC1 PC0   Port C"

Dann versteh ich nämlich nicht ganz, wie du von 30h (was ja binär
110000) sein müsste auf 0bxxx0011 kommst... oder beziehst du dich da
jetzt auf meine Belegung? (letzteres macht für mich gerade auch keinen
Sinn)
Die Verwirrung ist groß ^^


Danke!!!

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte etwas abgekürzt. Weil D0-D3 am Display auf GND liegen.
vollständig und korrekt Korrekt wäre natürlich 0x00110000b !!
Somit Interpretiert das Display die 3 als 30. Es sieht ja unten immer
0.
Halte Dich an meinen Vorschlag und dann kriegen wir das hin.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also gut, dann nochmal für Idoten:
Wenn ich deine Pin-Belgung verwende:

"Folgender Vorschlag:
       0b 0  0   0    0   0   0   0   0    Bits binär
             E  RS   RW  DB7 DB6 DB5 DB4   Display
            PC6 PC5  PC4 PC3 PC2 PC1 PC0   Port C"

und dann in kleinen Zeitabständen deine Werte rübersende:
"30h,30h,30h,20h,28h,08h,01h,06h,0fh", dann ist das Display
vernünftig initialisiert?

Bitte entschuldige meine Schwerfälligkeit - das ist eigentlich nicht
meine Art. Aber in diesem Fall stehe ich so derbe auf der Leitung, das
gibt's garnicht ;-)
Ich denke wenn das Ding erstmal läuft macht's auch mehr Spass damit
rum zu experimentieren. Aber so lange man garichts sieht ist das alles
eher frustrierend...

1000 Dank für deine Geduld. Du bist ein echter Held für mich :-D

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so siehts aus, allerdings hast Du dann erstmal nur den Kursor zu sehen.

Also 1. Eable setzen, RW,RS, Wert Ausgeben, Enable low

Wie gesagt, ab 20h mußt Du dann zerlegen in Low und High nibble.
4 Bit Modus.
Beim Lesen vom Display auch in 2 Schritten.
Ich habe bei mir RW fest auf MAsse, da ich nicht lesen will und nutze
eine feste Zeit von 5-6ms. Das reicht immer und ist immer noch schnell
genug. 2x16 schaffe ich damit ca. 4 Aktualisierung/Minute.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, da bin ich wieder :-D
Ich hab mir in der Zwischenzeit jede menge Zeug angelesen, da das alles
einfach nicht funktionieren wollte. Nun war der Meinung, die
Initialisierung endlich hinzubekommen.

Dann habe ich mit diesem Simulator herumgespielt:
http://www.geocities.com/dinceraydin/djlcdsim/djlcdsim.html
und bin zu folgender Befehlsreihenfolge gekommen, die wenigstens einen
blinkenden Cursor erzeugen sollte:


Erst 3 mal DB5 und DB4 an  -> Init 8 bit Modus

Dann nur DB5 an  -> Jetzt in 4 Bit wechseln

Dann alle aus -> Upper Nibble
Dann alle an  -> Lower Nibble -> Jetzt müsste Display AN, Cursor AN und
Blinken AN sein


Der Code dazu sieht so aus:
Belegung:
  //    PC7    PC6    PC5    PC4    PC3    PC2    PC1    PC0
  //  0b  0    0    0    0    0    0    0    0
  //    None  E    RS    None  D7    D6    D5    D4

Dann:

void enable( void )
{
  PORTC |= (1<<PC6);
}

void disable( void )
{
  PORTC &= ~(1<<PC6);
}



void initDisplay( void )
{

  //    PC7    PC6    PC5    PC4    PC3    PC2    PC1    PC0
  //  0b  0    0    0    0    0    0    0    0
  //    None  E    RS    None  D7    D6    D5    D4

WaitMs(30);

  disable();
  PORTC = 0b00000011;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000011;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000011;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000010;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000000;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00001111;
  enable();

WaitMs(30);

}

ABER IMMERNOCH STREIKT DAS BLÖDE DING UND ZEIGT NUR SCHWARZE
KÄSTCHEN!!! Das kann doch nicht wahr sein!?!?! :-(

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilfe! :-D

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WaitMs(30);

  disable();
  PORTC = 0b00000010;
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000000;
  enable();

WaitMs(30);

hier fehlt noch ne Null !!!!!
Du willst doch 0Fh schreiben oder nicht ???

zB.: disable ();
     portc = 0b00000000;
     lalala


  disable();
  PORTC = 0b00001111;
  enable();

WaitMs(30);

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh, du hast Recht. Es fehlt tatsächlich eine 0.
Hab also folgendes draus gebastelt:

WaitMs(30);

  disable();
  PORTC = 0b00000011;     // 8Bit
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000011;     // 8Bit
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000011;     // 8Bit
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000010;     // Jetzt 4Bit
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000000;     // ...
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00000000;     // Alles anschalten
  enable();

WaitMs(30);

  disable();
  PORTC = 0b00001111;     // ...
  enable();

WaitMs(30);

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Es geht natürlich immer noch nicht! :-(

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast Du auch an die Signale für R/W E und RS gedacht ?????

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soweit ich weiß liest das LCD die Daten vom Port mit fallender Flanke am
Enable-Pin.
D.h. das müsste bei dir so aussehen:

DDRC = 0xFF //alle Pins an Port C als Ausgang

WaitMS(20); //am Anfang reichen 20ms
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000011;  //8-Bit
PORTC &= ~(1<<PC6);  //Enable-Pin Low

WaitMS(5);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000011;  //8-Bit
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000011;  //8-Bit
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000010;  //4-Bit Modus - MSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(1);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000000;  //4-Bit Modus - LSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

WaitMS(20);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000010;  //4-Bit Modus - MSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(1);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000000;  //4-Bit Modus . LSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000000;  //Display AN, Cursor AN - MSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(1);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01001100;  //Display AN, Cursor AN - LSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01001000;  //DD-RAM Position 0 - MSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(1);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01000000;  //DD-RAM Position 0 - LSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01100100;  //Schreibt ein A - MSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(1);
PORTC |= (1 << PC6); //Enable-Pin High
PORTC = 0b01100001;  //Schreibt ein A - LSB
PORTC &= ~(1<<PC6);  //Enable-Pin Low
WaitUS(160);

WaitUS(x) wartet x µs, ich weiß nicht, wie die Funktion bei dir dafür
heißt, ich benutze delay.h von WinAVR (einbinden über #include
<util/delay.h>) dort heißt es "_delay_us(x)".

So funktioniert es bei mir einwandfrei

Zwei Hilfreiche Links sind auch:
http://www.myke.com/lcd.htm
http://www.ulrichradig.de/site/atmel/avr_lcd/pdf/LC.pdf

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stephan
Ja, ich denke schon:
- RS ist bei mir an PC5, also in allen meinen Binärcodes = 0. =>
Befehlsmodus
- RW hab ich nicht verwendet, ist an GND gelötet. => Schreibzugriff
- E setze ich ja immer mit enable/disable vor und nach jedem Befehl,
den ich übertragen möchte (siehe Code)

Ist doch richtig so, oder?


@Peter
Bei fallender Flanke also? Nagut, hab meine Funktionen "enable" und
"disable" mal vertauscht (die machen

PORTC |= (1 << PC6); //Enable-Pin High
PORTC &= ~(1<<PC6);  //Enable-Pin Low

genau wie in deinem Code).

Leider bringt das immer noch nichts. Nach wie vor nur 8 schwarze
Kästchen, und die andere Hälfte komplet leer :-(

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kurze Frage an peter: Warum hast du in allen deinen Befehlscodes (z.B.
0b01000011) an der zweiten Stelle nach dem b eine 1?
Ich verwende ja auch diesen Code, bei mir ist's allerdings 0b00000011,
also nur DB4 und DB5 an. Ist da noch was wichtiges an diesem Pin?

Und für alle Ideen, die zur Lösung meines Problems beitragen bin ich
natürlich absolut dankbar!!!

Autor: Daniel M. (usul27)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am Pin 6 hängt nach deiner Aussage weiter oben das Enable-Signal! Das
darfst du natürlich nicht wieder auf 0 setzen, während du Daten
schickst!

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Au verdammt! Das macht Sinn ^^ ich werd's gleich heut Mittag testen!
Danke :-)

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir (1x16 LCD) kann ich auch nur an den ersten 8 Stellen etwas
anzeigen, die hinteren 8 bleiben einfach leer. Ich dachte, dass mein
Display kaputt sei, denn wenn ich den Kontrast erhöhe sehe ich ganz
schwach Kästchen. Ich habe auch mal versucht, ob die hinteren acht
Stellen vom Controller vielleicht als zweite Zeile angesteuert werden,
aber das hat auch nicht funktioniert.
Hat dafür vielleicht jemand eine Lösung?

@Michael
Bist du dir sicher, dass dein Timing stimmt und die Funktion WaitMS(x)
auch x Millisekunden wartet?
Ich weiß von _delay_ms(x), dass die nur y / Mhz Millisekunden warten
kann, wobei y irgendeine Zahl ist, die ich gerade nicht mehr weiß.

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ebengerade noch einmal versucht mein Display im 2-Zeilen Modus
anzusteuern und es hat doch funktioniert. Das liegt wahrscheinlich an
den Adressen der Zeichen (vermutlich: 80..87, C1..C7; ich war von 80
bis 8F ausgegangen).
Als Lösung habe ich meine Routine so umgeschrieben, das sie ab einem
Spaltenindex von 8 automatisch in die 2. Zeile umspringt und man das
Display nun wie ein 1x16 LCD ansteuern kann.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welches Display ist denn das, Peter? Sowas hab ich auch noch nicht
gesehen.

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das 1x16 Zeilen LCD von Reichelt (LCD 161A).
Auf die Sache mit den Adressen bin ich durch diese PDF (Seite 4):
http://www.ulrichradig.de/site/atmel/avr_lcd/pdf/LC.pdf gekommen.

In meinem Datenblatt habe ich aber nichts zu den Adressen für die
Spalten gefunden.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mittlerweile sieht der Code so aus:


void enable( void )
{
  PORTC |= (1<<PC6);
}

void disable( void )
{
  PORTC &= ~(1<<PC6);
}



void initDisplay( void )
{

  //    PC7    PC6    PC5    PC4    PC3    PC2    PC1    PC0
  //  0b  0    0    0    0    0    0    0    0
  //    None  E    RS    None  D7    D6    D5    D4

WaitMs(30);

  enable();        // Setze E auf 1
  PORTC = 0b01000011;    // Befehl
  disable();        // Jetzt E auf 0 -> fallende Flanke

WaitMs(30);

  enable();
  PORTC = 0b01000011;
  disable();

WaitMs(30);

  enable();
  PORTC = 0b01000011;
  disable();

WaitMs(30);

  enable();
  PORTC = 0b01000010;
  disable();

WaitMs(30);

  enable();
  PORTC = 0b01000000;
  disable();

WaitMs(30);

  enable();
  PORTC = 0b01000000;
  disable();

WaitMs(30);

  enable();
  PORTC = 0b01001111;
  disable();

WaitMs(30);

}


Und ratet was passiert? Genau! Schwarze Kästchen!!!!!!
ICH BEKOMM HIER GLEICH NEN NERVENZUSAMMENBRUCH VERDAMMT!!!!!!  ^^
Das kann doch echt nicht wahr sein.... gibt es sonst noch Tips?

(Mal wieder vielen Dank an alle Mithelfenden!)

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß nicht, ob das eine Rolle spielt, aber für "normale" Befehle
reicht es, wenn man 160µs nach jedem Byte wartet.
Am Anfang (nach dem Spannung angelegt wurde) 15ms und 5ms für "Clear
Display" und "Cursor Home".
Zwischen MSB und LSB muss eigentlich nur ganz kurz (ich glaube 500ns)
gewartet werden.

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es würde auch helfen, wenn du mal deine komplette C-Datei anhängen
könntest. Vielleicht liegt der Fehler ja an einer ganz anderen Stelle.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Was hast du überhaupt für eine Prozessorclock?
2. Du musst das DDR Register zu Anfang auf Ausgang bei PORTC stellen.
3. Am besten ziehst du Enable, bevor du irngdwas am Display machst,
erstmal auf High.

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

Bewertung
0 lesenswert
nicht lesenswert
1) Also das mit dem Timing ist OK. Meine Funktion wartet eher zu lang
als zu kurz, was ja kein Problem ist, oder?
Ich benutze die auch um eine LED blinken zu lassen (mit 100ms, das
sieht schon ganz OK aus).

2) Das hab ich wohl gemacht.

3) OK, da muss ich nochmal gucken... ;-)


Die C-Datei findet sich im Anhang.

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn ich mein Display einfach nur initialisiere ohne Daten ins
DD-RAM zu schreiben bekomme ich auch nur schwarze Kästchen angezeigt.

Schreibe mal noch folgendes an das Display: (hinter deinem bisherigen
initDisplay)

  enable();
  PORTC = 0b01001000;
  disable();
WaitMS(1);

  enable();
  PORTC = 0b01000000;
  disable();
WaitMS(5);

  enable();
  PORTC = 0b01100100;
  disable();
WaitMS(1);

  enable();
  PORTC = 0b01100001;
  disable();
WaitMS(5);

Und verkürze die Wartezeiten zwischen MSB und LSB mal auf 1ms.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werd's gleich mal testen. Aber eigentlich sagt mein letzter
Befehl:
"Display ein, Cursor ein, Blinken ein"
Beim Simulator funktioniert's auch, da ist dann ein blinkender Cursor
zu sehen.....

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat leider auch nüscht geholfen :-(

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du jetzt mal bitte dein komplettes Programm zippen und anhängen?


Und mach mal zwischen enable und disable n paar takte pause, vielleicht
ist der abstand einfach zu kurz und dein Display bekommts nicht mit.
Immerhin kommen enable und disable fast im darauffolgenden Takt. Soviel
ich weiß muss enable aber auch ne bestimmte mindestzeit auf High stehen.


  enable();
  PORTC = 0b01100100;
  //hier warten
  disable();

Gruß Andreas

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erst Enable high ; das Display wieß..Ah jetzt kommt was für mich
dann RSund RW ; das Display wieß , Ah... Komando/ Daten,
schreiben/lesen
jetzt die Daten ;
und jetzt Enable auf Low; Display.... OK hab ich !!


In der Reihenfolge.

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Plattform und welchen Takt nutzt du eigentlich?

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan:
"erst Enable high ; das Display wieß..Ah jetzt kommt was für mich
dann RSund RW ; das Display wieß , Ah... Komando/ Daten,
schreiben/lesen
jetzt die Daten ;
und jetzt Enable auf Low; Display.... OK hab ich !!"

Dieser Textblock ist syntaktisch etwas merkwürdig... ich bin nicht
sicher, ob ich den richtig lesen kann ;-)


@Andreas:
Es ist ein AVR Mega16, mit einem 11 Mhz Quarz...oder was mainst du?

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne Frage zu deinem Code:

void enable( void )
{
  PORTC |= (1<<PC6);
}

PORTC |= (1<<PC6); ??? macht man das so bei einem AVR? Bitschubsen für
das setzen eines einzelnen PortPins.
Ich kenn das halt vom MSP430 anders oder versteh ich die drei Zeilen
nicht?
Steuer mein Display allerdings auch nur im 8bit-Modus an.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, ich denke das geht klar so. Das 6te Bit (hier an E) wird damit
angeknipst :-)

PS: Das komplette Programm hab ich schon geposted, hängt ein bisschen
weiter oben an :-)

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Marcel: Ja das macht man so. Was er da macht ist normale Bitmaskierung.
Geschoben wird (ein halbwegs intelligenter Copiler vorausgesetzt) an der
Stelle gar nicht: Das ganze kann schon zur compile-zeit als Konstante
berechnet werden (in diesem fall 00100000).

@Michael: Genau das meinte ich - 11 Mhz Quarz bedeutet 1 Takt braucht
ca 90ns (1/11000000 = 9,0909... x 10e-8). Schau mal wieviele ns das
enable signal high sein muss (Datenblatt)

Und poste endlich mal deinen kompletten Code, damit wir sehen was du
machst!

Gruß Andreas

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan:
""
erst Enable high ; das Display wieß..Ah jetzt kommt was für mich
dann RSund RW ; das Display wieß , Ah... Komando/ Daten,
schreiben/lesen
jetzt die Daten ;
und jetzt Enable auf Low; Display.... OK hab ich !!
""

Das ist übrigens Quark.

Wichtig ist: Zur Zeit, wo Enable von High auf Low wechselt, müssen
einfach nur die Datenleitungen und die RS+RW Leitungen valide Daten
aufweisen. Mehr nicht. Nix mit "Ah jetzt weiß das Display"..

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Hier mal einen Ausschnitt aus meiner eigenen Lib, die übrigens mit
einem EA DOG-M (16*2) super läuft.
void lcd_cmd8(unsigned char cmd)
{
  
  LCD_PORT = (cmd & 0xF0) >> 4;
  
  LCD_PORT &= ~(1<<LCD_RS);

  LCD_PORT |= (1<<LCD_E);
  nop();
  nop();
  nop();
  nop();
  nop();
  nop();
  LCD_PORT &= ~(1<<LCD_E);
  
  nop();
  nop();
  nop();
  nop();
  nop();
  nop();

  LCD_PORT = (cmd & 0x0F);  

  LCD_PORT |= (1<<LCD_E);
  nop();
  nop();
  nop();
  nop();
  nop();
  nop();
  LCD_PORT &= ~(1<<LCD_E);

  _delay_us(30);
}

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon,

für gewöhnlich aktiviert man Bausteine bevor man sie mit Daten
füttert.
Und das passiert mit Enable.
Ich habe lediglich versucht es für Michael verständlich auszudrücken,
( bildlich gesprochen ) sozusagen. Er scheint ja nicht mal die
Vorschläge von ganz oben porbiert zu haben, sonst hätte er ja nicht
knapp 80 Einträge im Tread. Und das erst beim INIT. .......

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan:

Richtig. Das Display aktiviert man eben, indem man Enable auf low
zieht. Wenn Enable high ist, dann macht das Display rein garnichts.


Ehrlichgesagt schätze ich mal, dass die Probleme timingbedingt sind.

PS: Bei PORTC fällt mir immer JTAG Interface ein. Hast du das per Fuse
ausgeschaltet?

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und versuche mal statt der Timerversion busy wait zu nehmen um
auszuschließen, dass es daran liegt. Nimm mal für Pausen die
_delay_ms() Funktion der libc.

Gruß Andreas

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon,

Zitat: "Das Display überwacht den Pegel von ENABLE. Ändert sich dieser
Pegel von Low nach High, dann fragt es die Leitungen RS und R/W ab
etc.pp :"

nachzulesen bei Sprut und im Datenblatt !!!
Es heist Enable und nicht /Enable

ergo..... es ist High aktiv.....

aber warscheinlich auch nur Quark !!!!

Meine Display gehen jedenfalls sehr gut !!
Und du solltest auch Hausaufgaben machen so wie Michael.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Er scheint ja nicht mal die Vorschläge von ganz oben porbiert zu
haben"
glaub mir, ich HABE SO ZIEMLICH ALLES probiert. Ich kann mir auch nicht
erklären woran's hapert.... aber ich werde da mal zusätzliche delays
einbauen, so wie ihr das vorgeschlagen habt.

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum nimmst Du nicht mal die fertigen Routinen ???? wie ganz oben
erwähnt ?? Die müssen gehen, sonst stimmt was ganz und gar nicht !!!

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, aber

@Stephan:

Nein, das ist falsch. Auch wenn es nicht /Enable heißt (das / ist kein
Muss), übernimmt das Display die Daten bei der fallenden Flanke.

http://web.media.mit.edu/~ayah/documents/hd44780u.pdf

Seite 58. Die Daten müssen bei der fallenden Enable-Flanke erst korrekt
anliegen, Basta.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt überall noch kleine Delays (1 ms) eingebaut, wenn ich das
E-Bit ändere. Damit sollte es jetzt also auch keine Probleme mehr
geben...
Leider hat das ganze noch immer keine Wirkung gezeigt :-(

Mit den Fremdbibliotheken ist so eine Sache... die sind quasi garnicht
dokumentiert (keine Tutorials oder Referenz so weit ich sehen kann).
Und da sind krass viele merkwürdige Konstanten drin, die man wohl
irgendwie setzen muss, die ich aber nicht verstehe :-(

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuche einfachmal folgenden Code für die LCD-Ansteuerung zu verwenden,
bei mir funktioniert dieser einwandfrei. Wenn es auch damit nicht geht
liegt das Problem woanders.
#include <util/delay.h>

#define ENABLE_PIN 6
#define RS_PIN 5

void LCDenable(void)
{
  PORTC |= (1 << ENABLE_PIN);
  _delay_loop_1(2);
  PORTC &= ~(1 << ENABLE_PIN);
}

void LCDwrite(char Data,char rs)
{
  DDRC = 0xFF;
  if (rs == 0)
  {
    PORTC &= ~(1 << RS_PIN); //rs == 0 -> Steuerregister
  } else {
    PORTC |= (1 << RS_PIN); //rs == 1 -> Datenregister
  }
  PORTC = (PORTC&0xF0) + ((Data&0xF0)>>4); //Write Nibbel MSB
  LCDenable();
  PORTD = (PORTC&0xF0) + (Data&0x0F); //Write Nibbel LSB
  LCDenable();
  _delay_us(160);
}

void LCDclear (void)
{

  LCDwrite (1,0); //Clear Display
  _delay_ms(5);
  LCDwrite (0x80,0);  //Set DD-Ram Adresse = 0
}

void LCDinit(void)
{
  DDRC = 0xFF;
  _delay_ms(20);
  LCDwrite(0x30,0);
  _delay_ms(5);
  LCDwrite(0x30,0);
  LCDwrite(0x30,0);
  LCDwrite(0x28,0); //LCD in 4bit Modus - 2 Zeilen
  _delay_ms(20);
  LCDwrite(0x28,0); //LCD in 4bit Modus - 2 Zeilen
  LCDwrite(0x06,0); //Cursor wird nach schreiben nach rechts verschoben
  LCDwrite(0x0C,0); //Display an, Cursor aus, Blink_Cursor aus
  LCDwrite(0x80,0); //Set DD-Ram Adresse = 0 | 1000 0000 | 1=DD-Ram
0000000=Adresse
}

int main(void)
{
  LCDinit();
  LCDclear();
  LCDwrite(0x54,1);
  LCDwrite(0x65,1);
  LCDwrite(0x73,1);
  LCDwrite(0x74,1);
}

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
den Zeilenumbruch zwischen 50 und 51 müsstest du noch entfernen

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochetwas: in Zeile 24 steht noch "PORTD" das muss bei dir "PORTC"
heißen.

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du denn die Vorschläge von oben schon probiert:

- PortC überprüfen (JTAG o.ä. deaktiviert?), oder nimm mal einen andern
Port.

- schmeiß deine eigene Wartroutine weg, ich wette es liegt am Timing.
Nimm zum testen mal die busy-wait routine _delay_ms(...)

Gruß Andreas

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Erstmal vielen Dank für deinen Code! Leider bringt auch der keine
Veränderung: nach wie vor nur 8 schwarze Kästchen.
Ich denke mal wir haben die gleiche Pinbelegung, ja? (zumindest RS und
E sind schonmal korekt).....
Woran könnte es denn dann liegen?

@Andreas:
Ich hab zwar keine Ahnung wer oder was JTAG ist, aber der Port scheint
OK zu sein. Hab auch mal alles an Port A gehängt (natürlich Software
entsprechend geändert), hat aber auch nicht geholfen.

Die Ports sind aber OK, ich hab LED-blink-Tests damit gemacht, und
jeder Pin ist OK.

Ich habe auch mit nem Multimeter geprüft, ob die Pins vom AVR gut mit
dem Display verlötet sind. Das scheint ebenfalls so zu sein...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn du nichts verändert hast an den Fuse-Bits dann IST JTAG nunmal
aktiviert. Kann ich mir garnicht vorstellen dass die Portbits vernünftig
funktionieren... ?!

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß leider immer noch nicht so genau was es mit diesem JTAG auf
sich hat. Hier auf der Seite und bei Wikipedia wird das nich vernünftig
erklärt.... was ist denn das?

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael Ich hatte den Code auf deine Pin-Belegung umgeändert.

Du musst über die Fuse-Bits JTAG deaktivieren.
Näheres zu den Einstellungen findest du im Datenblatt von deinem
Controller (bei Fuse-Bits oder JTAG nachschauen).

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe mit PonyProg mal die "Configuration Bits" eingelesen.
Dagibt es eins das "JTAGEN" heißt, das ist aber schon an.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Du musst über die Fuse-Bits JTAG deaktivieren."

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, sorry! Was ich eigentlch noch sagen wollte war, dass es aber leider
keinen Unterschied macht, ob das Kästchen an ist oder nicht.
Funzt nach wie vor nicht :-(

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorschlag zur systematischen Fehlersuche:

1. Verwende bewährte Software (z.B. peter fleury´s lib)
2. Nehme die entsprechenden Einstellungen in der Software vor, meistens
nur im Kopf der Quelltexte nötig
3. Baue Deine Schaltung komplett neu auf, nach den getroffenen
Vorgaben, um zu verhindern, dass Du murks verdrahtet hast
4. Verwende ggf. R/W um die Busy Flag auslesen zu können.
5. Setze ggf. die Taktung Deines MC in der Configuaration herunter, da
zu hohe Datenraten nicht verarbeitet werden
6. Mit Strom auf dem Module regele den Kontrast mit einem Poti an Pin 3
so ein, das die schwarzen Kästen gerade noch zu sehen sind

Dann kannst Du immer noch Deine eigene (Code-) Suppe kochen und die
Performance steigern.
Sollte es immer noch nicht funktionieren versuche ggf. ein anderes
Display.


Viel Glück

Autor: AndreasB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh ich hoffe deine "LED-Blink-Tests" hast du nicht direkt am Bus
gemacht? Dann könnte es sein, dass die Spannung die an den LEDs abfällt
zu groß ist und die übrige Spannung nicht mehr eindeutig genug ist..

Nochmals die andere Frage: Hast du endlcih deine Warteroutine
weggeworfen??

Gruß Andreas

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.