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!
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
>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...
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..
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 :-)
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!?!?!
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.
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)...
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
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 !!!!
> 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.
@ 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.
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...
>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...
@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...
<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
@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
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...
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
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
>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...
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!!!
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.
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
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.
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!?!?! :-(
@ 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 :-(
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!!!
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ß.
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.
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.
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.
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.
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.
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.
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.....
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
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.
@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?
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.
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 :-)
@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
@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"..
@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. .......
@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?
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
@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.
"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.
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.
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 :-(
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.
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
@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...
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... ?!
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?
@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).
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 :-(
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
Ä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