Forum: Compiler & IDEs und wieder mal ein KS0066U


von Vitali H. (vitali77)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe schon einiges zu diesem Thema hier im Forum gefunden. Komme 
jedoch immer noch nicht weiter. Ich bin noch ziemlich am Anfang der
C-Programmierung. Bis jetzt habe ich erst ein paar LED´s und
7-Segmenanzeigen angesteuert. Jetzt versuche ich es mit einem LCD und 
komme seit Tage nicht forwärts. Ich arbeite nach einem Buch, wo ich auch 
die Beispielroutiene her habe. Jedoch muss ich diese für mein Board 
anpassen. Das Display soll also im 4-Bitmodus laufen und ist 
folgendermaßen angeschlossen:

RS = PD2
E  = PD3
D4 = PD4
D5 = PD5
D6 = PD6
D7 = PD7

Die Routiene ist laut Buch für ein HD44780.
Laut Datenblätter sind jedoch beide zum größten Teil gleich.
Der Quelltext ist "angepasst", die Komentare jedoch nicht. Bitte nicht 
verwirren lassen. Währe wirklich super wenn mir da jemand ein Tipp geben 
könnte.

Bedanke mich im Voraus.

Gruß, Vitali

von Micha (Gast)


Lesenswert?

>Laut Datenblätter sind jedoch beide zum größten Teil gleich.
Eben nur "zum größten Teil". Sieh dir mal die jeweilige Initialisierung 
genauer an.

Ich weiß nicht aus welchem Buch der Code stammt, aber evtl. gibt es im 
Netz übersichtlicheren Code. Nicht dass dieser hier extrem schlecht 
wäre, aber übersichtlich finde ich ihn nicht wirklich.

Falls das nicht weiterhilft und du diesen Code verwenden willst, 
solltest du noch verraten welchen Controller du einsetzt und wie deine 
main aussieht.

von Peter D. (peda)


Lesenswert?

Das Problem bei vielen LCD-Libs ist, daß sie nicht an beliebige Pins 
anpaßbar sind oder sehr groß und unübersichtlich. Dadurch entstehen dann 
die meisten Fehler.

Hier ein kleines einfaches Beispiel für beliebige Pins.
Es benutzt außerdem die besonders übersichtliche Definition von Portpins 
als Bitvariablen im AVR-GCC:

http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip


Peter

von Vitali H. (vitali77)


Lesenswert?

Hallo zusammen

Habe mir beide Datenblätter noch eimal angeschaut.
Bezüglich Initialisierung sehen beide soweit gleich aus.
Ich muss den Code nicht unbedingt verwenden, würde ihn aber gerne 
verstehen. Ich habe mir schon einige Beispielroutinen aus dem Netz 
besorgt, die ich zum größten Teil verstanden und auch zum laufen 
gebracht habe. Der Quelltext von Peter ist ebenfalls sehr übersichtlich.
uC ist übrigens ein mega16.


Gruß, Vitai

von Micha (Gast)


Lesenswert?

>Der Quelltext von Peter ist ebenfalls sehr übersichtlich.
Na dann würde ich dir auf jeden Fall raten den zu nehmen. Bei Peter's 
Sachen weiß man was man hat und dass es funktioniert...

von Vitali H. (vitali77)


Angehängte Dateien:

Lesenswert?

ich möchte trotzdem verstehen was der Code aus dem Buch genau macht.
Habe das ganze nun soweit dass wenigstens ettwas auf dem display 
erscheint.
Die Ausgabe ist jedoch ein reines kudelmudel. Ich denke das Problem ist 
beim setzen des 4-Bit-Modus. Ausserdem verstehe ich die "lcd_write" 
Fuktion nicht so ganz:

void lcd_write (uint8_t data, uint8_t rs)
{
uint8_t dataBits ;

if (rs)        // write data (RS=1, RW=0)
dataBits=0b00000100;  // RS liegt an Pin 2
else           // write instruction (RS=0, RW=0)
dataBits=0;

PORTD = dataBits | (data|0b11110000);// output high nibble first, zzgl. 
Zustand für RS-Leitung
lcd_flash_e ();

PORTD = dataBits | (data&0b11110000);// output low nibble, zzgl. 
RS-Leitung
lcd_flash_e ();
}

kann mir das jemad erklähren?

Gruß, Vitali

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>  4-Bit-Modus
1
// PC0-PC3 = D4-D7  <<--- DER KOMMENTAR IST FALSCH
2
3
PORTD = dataBits | (data|0b11110000);// output high nibble first, 
4
lcd_flash_e ();
5
6
PORTD = dataBits | (data&0b11110000);// output low nibble
7
lcd_flash_e ();
Der Code wird so nicht funktionieren.
Wenn auf den unteren 4 Bits von Port D die Datenleitungen für den 
4-Bit-Modus (D7-D4) angeschlossen sind, dann muß data in zwei Nibbles 
darauf abgebildet werden. Zuerst das High-Nibble, dann das Low-Nibble.
Aber beide Zuweisungen sind nicht korrekt.

Zudem muß vor dem zweiten Zuweisen von Daten an dataBits der 
ursprüngliche Zustand wiederhergestellt werden.

Wozu eigentlich diese Variable, wenn sowieso dirket auf dem Port 
herumgebastelt wird?

Besser wäre es so:
1
// PD3-PD0 = D7-D4
2
3
if (rs)  rs=0b00000100;        // RS liegt an PD2
4
5
PORTD = rs | ((data>>4)&0x0f); // output high nibble first; 0b00001111 = 0x0f
6
lcd_flash_e ();
7
8
PORTD = rs | ( data    &0x0f); // output low nibble
9
lcd_flash_e ();

von SF (Gast)


Lesenswert?

Noch Besser wäre es so (LCD ist an PD7-PD4 angeschlossen, nicht 
PD3-PD0):
1
if (rs)  rs = (1<<PD2);        // RS soll gesetzt werden, RS liegt an PD2, also wird es "hinzugemischt"
2
3
PORTD = rs | ( data    &0xf0); // output high nibble und RS
4
lcd_flash_e ();
5
6
PORTD = rs | ((data<<4)&0xf0); // low nibble ins high nibbel schieben und output low nibble und RS
7
lcd_flash_e ();

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Noch Besser wäre es so...
Ok, ich seh's ein, ganz oben steht die Pinzuordnung. Mein Code gibt ein 
wenig Mischmasch auf dem unteren Nibble. Aber wenn du dir den 
Original-Code und die Kommentare anschaust, solltest man mir das nochmal 
nachsehen können ;-)

von Vitali H. (vitali77)


Lesenswert?

erst eimal danke ich euch dass Ihr euch die Sache mal angeschaut habt.
Ich weiß, der Code ist sehr verwirrend. Landsam frage ich mich warum ich 
mir das Buch gekauft habe. Es soll jedoch für Anfänger sein. Was die 
Elektronik angeht ist eigentlich alles gut beschrieben.
Die Komentare im Quelltext stören ein wenig, ich wollte jedoch erst 
aufräumen wenn das Ding läuft. Ich hatte oben schonb kurz erwähnt dass 
bei mir das LCD wie folgt angeschlossen ist.

RS = PD2
E  = PD3
D4 = PD4
D5 = PD5
D6 = PD6
D7 = PD7

Es läuft auch sowei, dass ich eine vernünftige Ausgabe bekomme. Jedoch 
switcht das Ausgabeformat nach jedem Reset von richtig nach Kudelmudel 
und wieder umgekehrt. Es kommt mir vor als ob das LCD nicht richtig in 
den
4-Bitmodus schaltet. Die Funktion sieht bei mir so aus:

void lcd_set4bit ()
{

PORTD = 0x03;  //schalte in 8-Bit und wiederhole 2 mal
lcd_flash_e ();
delay_ms(5);

PORTD = 0x03;
lcd_flash_e ();
delay(200);

PORTD = 0x03;
lcd_flash_e ();
delay(200);

lcd_write(0b00100000,0);  //schalte in 4-Bit
delay(200);
}

Hier noch die "lcd_flash_e"

void lcd_flash_e ()
{
  PORTD |= (1<<DDD3);
  _delay_us(40);
  PORTD &= ~(1<<DDD3);
  _delay_ms(2);
}

Das sollte doch richtig sein, oder?


Gruß, Vitali

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> delay_ms(5);
Mir scheint die Zeit etwas kurz  :-/

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.