Forum: Mikrocontroller und Digitale Elektronik WinStar WG12864A (KS0108) am ATmega8


von Claire G. (bitterman)


Lesenswert?

Hallo Leute,

ich hab mir an mein selbstgebasteltes ATmega8-Board ein WinStar WG12864A 
(KS0108) LCD-Display dran gebaut. Aufgrund dessen, dass ich noch 2 
Taster und 2 LEDs dran hab, sind die Ports auch bald aufgebraucht. Es 
hat aber gereicht (PC und PB). Da ich nun Anfänger bin, hab ich ein 
AVR-GCC-Tutorial durchwühlt. Der dort verwende LCD-Controller ist ja nun 
doch ein anderer. Ich hab mir also mal ein Datenblatt vom KS0108 gezogen 
und ein bisschen angesehen. Ich werd aber daraus auch nicht so wirklich 
schlau. Ich will halt nicht immer fertigen Code sehen und mich danach 
richten. Es geht schon damit los, welche Bibliotheken brauche ich etc. 
Kennt jemand eine gute Quelle wo man sich das mal von Grund auf 
durchlesen und beibringen kann? Das Datenblatt allein reicht irgendwie 
überhaupt nicht. Es erklärt mir nicht wie ich am Ende programmieren 
muss.

Vielen Dank im Vorraus.

MfG

von Michael M. (moonuser)


Lesenswert?

Hallo Benjamin,

ich würde empfehlen, einen passenden Artikel und das Tut als Vorlage zu 
nehmen und die Datenblätter zu vergleichen.
In manchen Datenblättern fehlen die kleinen Details, was gerade 
schwierig ist, wenn man sich nicht 100 % auskennt.
Ich habe letzens 3 Abende gesessen um ein LCP zu 100% ans laufen zu 
bekommen.

Grüße

von Oliver (Gast)


Lesenswert?

>Kennt jemand eine gute Quelle wo man sich das mal von Grund auf
>durchlesen und beibringen kann?

Auch wenn du keinen "fertigen" Code willst, du kannst ihn dir ja 
wenigsten ansehen. Zusammen mit dem Datenblatt ist das der beste Weg. 
Wenn du verstehst, wie andere das Problem gelöst haben, ist es ja kein 
Problem mehr, selber eine "ganz eigene" Lösung zu bauen (von der du 
spätestens in einem Jahr auch nicht mehr weißt, welche Bibiotheken nun 
dazugehören, und wie es im Detail funktioniert...)

Codebeispiele gibt es in der Codesammlung und auch sonst überall im 
Netz. Eine andere Quelle für solche Fragestellunge ist auch immer die 
avrlib (googlen). Deren Code ist zwar nicht unbedingt der beste, aber 
als Starthilfe reicht es allemal.

Oliver

von Claire G. (bitterman)


Lesenswert?

Vielen Dank für die Antworten.
So...unten wäre ein kleines Programm, welches einfach nur eine Linie 
erzeugen sollte. Ich sehe aber leider nichts auf dem LCD. Zuerst bin ich 
nochmal die Kontakte durchgegangen und siehe da, Chip Select I war nicht 
korrekt verdrahtet. Nun sehe ich aber trotzdem noch nichts. Eigentlich 
solltes am Code nicht liegen, könnte vielleicht trotzdem nochmal jmd. 
drüber schauen der sich mit dem Display auskennt.(Wenn das erforderlich 
ist)

Wäre sehr dankbar.
R/W ist übrigens auf GND.

Gruß

------------------------------------------------------------------------ 
--

void LCD1 (void)
{
//D/I = Instruction
PORTB &= ~(1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Display ON
PORTD = 0x3F;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));

//-------------------------------------------------
//D/I = Instruction
PORTB &= ~(1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Set Adress
PORTD = 0x40;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));

//-------------------------------------------------
//D/I = Instruction
PORTB &= ~(1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Set Page
PORTD = 0xB8;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));

//-------------------------------------------------
//D/I = Instruction
PORTB &= ~(1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Display Start Line
PORTD = 0xC0;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));

//-------------------------------------------------
//Data

//D/I = Data
PORTB |= (1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Write Data
PORTD = 0xF0;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));
}

von Claire G. (bitterman)


Lesenswert?

Bin heute die Schaltung nochmal durchgegangen, daran kanns nicht liegen. 
Hoffentlich ist das LCD nicht kaputt.^^
(Hatte mir die Kiste bei Ebay bestellt und erstmal für eine halbe 
Ewigkeit herumliegen lassen)
Ich hab R/W ja auf GND gelegt. Ich hab zudem gelesen, dass man manchmal 
den LCD-Ram auslesen muss. Könntes vielleicht daran liegen? Ansonsten 
muss es wohl am Code liegen, dass ich vielleicht da einen Denkfehler 
hab.

von Oliver (Gast)


Lesenswert?

>Ansonsten muss es wohl am Code liegen

Ziemlich sicher. Dummerweise kann man den kaum lesen.

Zur Prüfung, ob dein Aufbau in Ordnung ist, lade dir mal die ks0108-lib 
von APE aus der Codesammlung, und lass das Testprogramm laufen. Wenn das 
was anzeigt, ist die AHrdware in Ordnung. Allerdings braucht die auch 
R/W als Signal, aber das wirst du später eh auch benötigen.

Was hast du eigentlich mit dem Reset-Pin am Display gemacht? Ist die 
Hintergrundbeleuchtung an?

Oliver

von Oliver (Gast)


Lesenswert?

Eine Sache sind mir im Code doch aufgefallen:

//Display Start Line
PORTD = 0xC0;

zeigt keine Linie an, sondern setzt die "Display-Startline", d.h. es 
definiert die Null-Koordinate auf dem Display und verschiebt dann den 
ganzen Displayinhalt entsprechend.

Etwas auf das Diplay zu zeichen geht mit "Write display data". Das 
schreibt die 8 bit senkrecht übereinander an der aktuelle X-Position in 
der ausgewählten Page.

Oliver

von Claire G. (bitterman)


Lesenswert?

Hallo Oliver,
danke erstmal für deine Hilfe.

Ich versuche nochmal den Code zu erklären.
Ich habe im Internet einen Flowchart gefunden und nach dem richte ich 
mich.

1. D/I - Auswahl Daten/Befehl
2. Chip Select
3. --> Hier kommt der Befehl rein, 4x
   a) Display An
   b) set Adress
   c) set Page
   d) Start Line
(Das sind die ersten 4 Blöcke (durch gestrichelte Linien getrennt)
   e) Im letzten Block steht der Write Data Befehl
      (D/I =1)

4. Enable = 1
5. Kurz warten (nop)
6. Enable = 0
7. Kurz warten
8. Chip Select Disable


Der Reset-Pin geht auf +5V.
Ist der so wichtig?

Ich beschalte nachher gleich mal das R/W mit dem µC und probiere den 
vorgeschlagenen Code aus.

von Claire G. (bitterman)


Lesenswert?

Ich lege jetzt alles um.
Die Datenschiene bleibt auf PortD, die Befehlsschiene kommt jetzt 
komplett auf PortC, die Taster und die LED´s auf die paar PortB.
So lässt sich warscheinlich alles ein bisschen besser handlen bzw. wird 
übersichtlicher.
Zudem hab ich R/W und Reset auf einen Pin gelegt.
Morgen teste ich dann mal den Code.

Gruß Benjamin

von Oliver (Gast)


Lesenswert?

Prinzipiell ist der Ablauf richtig, das Timing dürfte aber noch nicht 
stimmen. Der Enable-Puls braucht eine bestimmte Länge, mit einem "nop" 
ist er z.B. bei 8MHz CPU-Frequenz schon zu kurz. Dazu kommt, daß das 
Display ziemlich lange braucht (aus CPU-Sicht), um einen Befehl 
auszuführen. Da musst du entweder das busy-flag abfragen, oder zwischen 
den Befehlen eine Weile warten.

Das du auf dem Display nichts siehst, liegt natürlich auch daran, daß 
dein Programm nichts zum Anzeigen an das Display schickt. Die 
Hintergrundbeleuchtung sollte allerdings schon angehen.

Oliver

von Claire G. (bitterman)


Lesenswert?

Also ich habs jetzt umgebaut und versucht fertigen Code anzupassen, hab 
nochn paar Probleme, aber das müsste hinzukriegen sein.
Also die CPU-Frequenz ist 1 MHz.
Die Hintergrundbeleuchtung geht jupp.

Ich dachte im Block 5 schreibe ich:

//-------------------------------------------------
//Data

//D/I = Data
PORTB |= (1 << PB0);

//Chip Select
PORTB |= (1 << PB6);
PORTB &= ~(1 << PB7);

//Write Data
PORTD = 0xF0;

//Enable = 1
PORTB |= (1 << PB1);
//kurz warten
asm ("nop");

//Enable = 0
PORTB &= ~(1 << PB1);
//kurz warten
asm ("nop");

//Disable Chip Select
PORTB &= ~((1 << PB6) | (1 << PB6));
}

---> PORTD = 0xF0;

von Tobi (Gast)


Lesenswert?

Hi, ich habe das selbe Display. Wärst du so nett und könntest deinen 
Schaltplan mal online stellen? Bin mir nämlich noch nicht so sicher, wie 
das mit der negativen Spannung funktioniert.
Sobald ich das ganze dann aufgebaut habe, helfe ich dir auch gern beim 
Quellcode, mit C kenn ich mich um einiges besser aus als mit der 
Elektronik ..

Viele Grüße
Tobi

von Michael S. (msk) Benutzerseite


Angehängte Dateien:

Lesenswert?

Der Thread ist zwar schon alt, aber trotzdem noch eine Antwort dazu 
(aktuell ist das Display nämlich wieder bei Pollin für 9,95 Euro 
verfügbar).

Laut Datenblatt ist die Beschaltung wie im Anhang dargestellt. Mehr als 
ein Poti scheint also nicht notwendig zu sein. Ich habe es aber noch 
nicht ausprobiert, das ist nur meine Interpretation des Datenblatts. ;)

Quelle Datenblatt:

http://www.pollin.de/shop/downloads/D120044D.PDF


Falls jemand gegenteilige Informationen oder Bedenken hat, dann immer 
her damit (bevor ich meine Displays damit um die Ecke bringe...) ;)

von Michael S. (msk) Benutzerseite


Lesenswert?

Was mir noch einfällt: Weiß jemand, ob bei diesem Display schon ein 
Vorwiderstand für das LED-Backlight auf der Platine ist? Das Datenblatt 
bei Pollin ist leider dahingehend nicht wirklich eindeutig (Seite 16). 
Dass in dem Datenblatt der Teil zum Backlight mehrfach geändert wurde 
und trotzdem nicht besonders eindeutig ist, macht mich da noch 
unsicherer...

von holger (Gast)


Lesenswert?

>Weiß jemand, ob bei diesem Display schon ein
>Vorwiderstand für das LED-Backlight auf der Platine ist?

Ausprobieren? Mach einen rein und gut.

von Michael S. (msk) Benutzerseite


Lesenswert?

holger schrieb:
> Ausprobieren? Mach einen rein und gut.

Wenn ich das schon vorher wüsste, könnte ich mir das Ausprobieren 
sparen. ;)

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.