Forum: Mikrocontroller und Digitale Elektronik STM32 und ks0108-Display - keine Anzeige


von Johannes S. (jhs)


Angehängte Dateien:

Lesenswert?

Hi!

Bin grad ziemlich am verzweifeln...

Ich habe eine Schaltung mit STM32 und einem MG1206B-Display aufgebaut. 
Schaltpläne siehe Ahnung. Dazu habe ich dann Ansteuercode für das 
Display geschrieben, aber leider sehe ich gar nichts außer schwarzes 
Flimmern am Display, dass gibts aber auch ohne uC.

Die Datenblätter zum Display sind hier:
* http://www.everbouquet.com.tw/MG1206B.htm
* 
http://www.ortodoxism.ro/datasheets2/e/0lz7coi0w34yg4tykozdpz9ox7cy.pdf

Soweit ich das verstanden habe:
* CS1/CS2 aktive High
* RESET aktive Low (also zum Reset auf low ziehen)

Der uC steuert das Display eigentlich korrekt an, am Oszi sah das ganze 
ziemlich genau so aus wie das Timing-Diagramm im Datenblatt. Allerdings 
sehe ich eben gar nichts außer eine Fläche auf der alle Pixel leuchten. 
Der Code ist angehängt, eigentlich sollten auf dem Display mehrere H 
erscheinen.

Hab das ganze auch mal testweise mit dem Simulator 
(http://www.geocities.com/dinceraydin/djgfxlcdsim/djgfxlcdsim.html) 
durchgetestet und dort kommt abgesehen von CS1/CS2 aktive Low auch genau 
die erwartete Ausgabe.

Wäre super, falls mir noch jemand einen Tipp geben kann.

Danke,
Johannes

von holger (Gast)


Lesenswert?

>aber leider sehe ich gar nichts außer schwarzes
>Flimmern am Display, dass gibts aber auch ohne uC.

Schliess den Trimmer mal richtig an. So ist der
Kontrast voll aufgedreht.

von Johannes S. (jhs)


Lesenswert?

Hi!

holger schrieb:
>>aber leider sehe ich gar nichts außer schwarzes
>>Flimmern am Display, dass gibts aber auch ohne uC.
>
> Schliess den Trimmer mal richtig an. So ist der
> Kontrast voll aufgedreht.

Ich kann den Trimmer von NULL-Kontrast bis Voll-Kontrast einstellen, 
aber da ich kein wirkliches Bild habe kann ich auch nicht sagen, wann 
der Kontrast richtig ist.

Aber stimmt, der Trimmer könnte ihm Schaltplan falsch sein, hab aber 
leider sowieso keinen in SMD gefunden und daher einen ganz normalen 
passend eingelötet, also so, dass er auch trimmt.

Trotzdem danke,
Johannes

von holger (Gast)


Lesenswert?

>Ich kann den Trimmer von NULL-Kontrast bis Voll-Kontrast einstellen,

Dann liegt es wohl an der Ansteuerung.
Dein uC ist ziemlich schnell. Der KS0108 aber stinkend langsam.
Den BusyCheck hab ich nie zum laufen bekommen und daher
immer mit Delays gearbeitet. Ich vermute mal ein Timing Problem.

von Johannes S. (jhs)


Lesenswert?

Hi!

Ich hab mit diversen Delays gearbeitet (bis zu 5us zwischen EN ON/OFF). 
Busy-Check ist laut Datenblatt normalerweise bei Mikrocontrollern 
(I/0-Ports) unnötig und wird nur gebraucht, wenn man Memory-Mapped IO 
verwendet (wie z.B. beim x86).

Laut meinen Messungen mit dem Oszi stimmen aber auch die Timings mit dem 
Datenblatt überein (mindenstes 1us EN-cycle und dabei ca. 500ns EN-ON 
und 500ns EN-OFF.

Eine kurze Frage zum Kontrast hätte ich aber noch: Was soll das Display 
wenn es nicht angesteuert wird zeigen? Sollen dann keine schwarzen Pixel 
zu sehen sein oder sind alle schwarz?

Danke,
Johannes

von holger (Gast)


Lesenswert?

>Laut meinen Messungen mit dem Oszi stimmen aber auch die Timings mit dem
>Datenblatt überein (mindenstes 1us EN-cycle und dabei ca. 500ns EN-ON
>und 500ns EN-OFF.

Viel zu kurz. Versuchs mal mit 5us EN-ON + 5us EN-OFF.
Ein altes Displaytech brauchte bei mir 4us. Eins von Pollin
nur 2us. Kommt drauf an wie schnell der Controller auf dem
Display getaktet ist.

>Eine kurze Frage zum Kontrast hätte ich aber noch: Was soll das Display
>wenn es nicht angesteuert wird zeigen? Sollen dann keine schwarzen Pixel
>zu sehen sein oder sind alle schwarz?

Eigentlich sollte es dann leer sein. Also keine schwarzen Pixel.

von NOP (Gast)


Lesenswert?

1
    /* Ein NOP entspricht ca. 130ns */
2
    asm("nop");

Ich meine im Programming Manual gelesen zu haben, daß der Cortex ein NOP 
nicht unbedingt ausführt, wenn er (flapsig) grade keine Lust hat. Er 
schmeißt ihn evtl schon vorher aus seiner Queue. Oder so. Leider stand 
dort nichts genaueres. Habe leider grade keinen Zugriff auf das Manual.

Jedenfalls bedeutet das wohl, daß ein NOP nicht unbedingt Zeit 
verbraucht.
- dadurch macht Deine Wrteschleife evtl nicht unbedingt das, was du 
erwartest.

Weiß jemand genaueres ?

von NOP (Gast)


Lesenswert?

... eigentlich gehört dort auch ein "volatile" hin. Bist Du sicher, daß 
Deine Warteschleife nicht komplett wegoptimiert wird ?

von NOP (Gast)


Lesenswert?

[quote]
NOP does nothing. NOP is not necessarily a time-consuming NOP. The 
processor might
remove it from the pipeline before it reaches the execution stage.
Use NOP for padding, for example to place the following instruction on a 
64-bit boundary.
Condition flags
This instruction does not change the flags.
[/quote]

Quelle: http://www.st.com/stonline/products/literature/pm/15491.pdf

Was lernt man daraus ? Ein NOP hat in C-Programmen für den Cortex-M3 
nicht viel Wert...
Nimm einen der Timer.. es gibt ja genug davon :-)
Dann bist du wenigstens Sicher, daß das Timing stimmt.


Trotzdem würde mich interessieren, was "The processor might
remove it from the pipeline before it reaches the execution stage." 
genau bedeutet. Wann genau trifft "might" zu ??

von (prx) A. K. (prx)


Lesenswert?

Die M3 Referenz legt nahe, dass sich die beiden verschiedenen NOPs in 
dieser Hinsicht unterscheiden und nur der 16-Bit NOP rausfliegen kann, 
der 32-Bit NOP jedoch nicht.

von NOP (Gast)


Lesenswert?

Wie lautet der Opcode für den 32-Bit nop ?
Ich zweifle an meinen Google-Fähigkeiten, aber ich finde nix :-(

Manchmal kann man sowas ja evtl. doch brauchen.
Ich vermute, der GCC nimmt den kürzen 16-Bit Nop, wenn man asm("nop") 
schreibt, oder ?

von Johannes S. (jhs)


Lesenswert?

Hi!

Also dank eines freundliche Vier-Kanal-Oszis weiß ich, dass das NOP 
nicht wegoptimiert wird. Allerdings habe ich inzwischen auch auf eine 
andere delay-Methode umgestellt - ohne das sich etwas geändert hätte. 
Wenn es mal läuft werde ich wohl einen Timer + Befehls-Queue verwenden.

Zum 32-bit NOP: Unterstützt der STM32 nicht nur Thumb-Befehlssatz, d.h. 
alle Befehle sind 16-bit?

Trotzdem bin ich leider nicht wirklich weitergekommen. Auch bei 5us oder 
10us EN-ON/OFF tut sich leider nix.

Habe jetzt als nächstes versucht den Status auszulesen und der bleibt 
tatsächlich immer auf Busy. Das Display zieht D0-D7 auf active High, 
wenn ich RW auf High setze.

Viel fällt mir nicht mehr ein. Das Datenblatt sagt, dass High Minimum 
0,7Vdd oder 2V sein muss, sollte als bei meinen ca. 3,4V kein Problem 
sein. Alle Verbindungen passen, alles kommt an den Eingängen vom Display 
an. Alles Versogungsspannungen hab ich auch nachgemessen. Bin noch am 
überlegen ob ich RESET einfach per Pull-up auf 5V lege, aber eigentlich 
sollten 3,4V ja ausreichen.

Ich frage mich, wie ich das Display dazu bringe, dass es nicht mehr Busy 
ist...

Danke,
Johannes

von Johannes S. (jhs)


Lesenswert?

NOP schrieb:
> /* Ein NOP entspricht ca. 130ns */
>     asm("nop");

Das war übrigens falsch! Vielleicht wurde das NOP an dieser Stelle sogar 
wegoptmiert, aber die for-Schleife braucht pro Durchlauf eben 130s 
(Einmal Increment + einmal Vergleich). Da alles mit -0s übersetzt ist, 
optimiert der Compiler eigentlich auch nichts weg.

Johannes

von (prx) A. K. (prx)


Lesenswert?

Johannes Schmid schrieb:

> Zum 32-bit NOP: Unterstützt der STM32 nicht nur Thumb-Befehlssatz, d.h.
> alle Befehle sind 16-bit?

Er kann Thumb2 und da ist recht viel in 32 Bits codiert. Aber neu 
codiert, das ist nicht der alte ARM Befehlssatz.

von Andre R. (ryan87)


Lesenswert?

Wie sieht denn deine Reset Sequenz aus?

Ich hab vor kurzem das erste mal ein 160x32 Dot-Matrix Display von 
Electronic Assembly angesteuert (mit ATmega644). Damit das Display 
zuverlässig funktionierte muss ich für einen Reset die Reset-Leitung 3x 
für 100ms(!) low ziehen, danach noch den Controller initialisieren 
(zeilen, spalten setzen).

Evtl. bekommst du so dein Display aus dem "Busy" Status.

von NOP (Gast)


Lesenswert?

>Da alles mit -0s übersetzt ist,
>optimiert der Compiler eigentlich auch nichts weg.

Wie meinen ?
:-)

von Johannes S. (jhs)


Lesenswert?

Hi!

Andre R. schrieb:
> Wie sieht denn deine Reset Sequenz aus?
>
> Ich hab vor kurzem das erste mal ein 160x32 Dot-Matrix Display von
> Electronic Assembly angesteuert (mit ATmega644). Damit das Display
> zuverlässig funktionierte muss ich für einen Reset die Reset-Leitung 3x
> für 100ms(!) low ziehen, danach noch den Controller initialisieren
> (zeilen, spalten setzen).
>
> Evtl. bekommst du so dein Display aus dem "Busy" Status.

Hmm, klingt ganz plausibel, ich werds mal ausprobieren.

Danke,
Johannes

von Johannes S. (jhs)


Lesenswert?

Hi!

NOP schrieb:
>>Da alles mit -0s übersetzt ist,
>>optimiert der Compiler eigentlich auch nichts weg.
>
> Wie meinen ?
> :-)

Kein LAUFZEIT-Optmierung...

Gruß
Johannes

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Pegel ???

VHi Min ist gleich Vdd * 0,7 = 3,5V !!!

Also kann das Display niemals ein Hi erkennen.

von (prx) A. K. (prx)


Lesenswert?

Markus Müller schrieb:

> Also kann das Display niemals ein Hi erkennen.

Bischen krass formuliert. Genauer: Es ist nicht gewährleistet, dass das 
Display Hi erkennt. Tatsächlich liegt die Schaltschwelle von CMOS meist 
um die Vcc/2 herum.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Muss ich den alles auf dem Silbernen Tablett vorkauen?

Datenblatt
http://www.datasheetcatalog.org/datasheet2/e/0lz7coi0w34yg4tykozdpz9ox7cy.pdf
Seite Vih1 = 0.7Vdd = 3,5V für die Pins unter Note (1)
Das wäre z.B. RSTB

Datenblatt
http://www.everbouquet.com.tw/MG1206B.htm
Ist das Pin 17

Also muss für diesen Pin der STM32 als "GPIO_Mode_Out_OD" definiert 
werden und es muss ein Pull-Up Widerstand auf +5V rein.

Das LCD wird also niemals sein Reset-Zustand zuverlässig verlassen 
können.

An Pin19 gehört sicher noch ein Vorwiderstand. Besser ist Pin19 an +5V, 
Pin20 mit Widerstand sind Transistor, den gesteuert mit einem 
Timer-Ausgang. Dann kann man das Display auch dimmen mit PWM.

von (prx) A. K. (prx)


Lesenswert?

NOP schrieb:

> Wie lautet der Opcode für den 32-Bit nop ?

16bit: 0xBF00.
32bit: 0xF3AF8000, offiziell NOP.W

von holger (Gast)


Lesenswert?

> Damit das Display
> zuverlässig funktionierte muss ich für einen Reset die Reset-Leitung 3x
> für 100ms(!) low ziehen, danach noch den Controller initialisieren
> (zeilen, spalten setzen).

Kann ich nicht bestätigen. Bei mir hängt der Reset an einem
AVR Pin. Beim einschalten floatet der. Dann setz ich ihn nur
auf High und gut. Vermutlich kann man den einfach per Pullup
hochziehen und dann nochn 100n gegen Masse. Als Init reicht
0x3F für Display on und 0xC0 für Display Start Line 0.
Das funktioniert so mit einem uralten Displaytech 64240A und einem
TG12864B von Pollin.

von Johannes S. (jhs)


Lesenswert?

Hi!

Markus Müller schrieb:
> Muss ich den alles auf dem Silbernen Tablett vorkauen?

Sorry, irgendwie hab ich mich in meinem Kopf mit den 0,7VDD total 
verrechnet (siehe auch Beitrag oben). Weiß auch nicht so genau, warum 
ich nicht auf die Spannungen geachtet habe, da ich auf der Platine für 
diverse andere Bauteile extra Pegelwandler verbaut habe.

> Datenblatt
> http://www.datasheetcatalog.org/datasheet2/e/0lz7c...
> Seite Vih1 = 0.7Vdd = 3,5V für die Pins unter Note (1)
> Das wäre z.B. RSTB
>
> Datenblatt
> http://www.everbouquet.com.tw/MG1206B.htm
> Ist das Pin 17
>
> Also muss für diesen Pin der STM32 als "GPIO_Mode_Out_OD" definiert
> werden und es muss ein Pull-Up Widerstand auf +5V rein.

Danke für die genaue Erklärung. Macht auch viel Sinn. Werds morgen 
probieren.

> An Pin19 gehört sicher noch ein Vorwiderstand. Besser ist Pin19 an +5V,
> Pin20 mit Widerstand sind Transistor, den gesteuert mit einem
> Timer-Ausgang. Dann kann man das Display auch dimmen mit PWM.

Ich meine diesen Vorwiderstand in keinem Datenblatt gesehen zu haben, 
aber ich lass mich gern eines besseren belehren. Die 
Hintergrundbeleuchtung funktioniert allerdings (noch?). Leider krieg ich 
keine zusätzlichen Timer-Ausgänge mehr raus, eh schon alles sehr eng. 
Was tut man nicht alles für
Raumzeigermodulation.

@Holger: Dein AtMega(?) arbeitet auch mit 5V, ein ARM normalerweise eben 
nur mit 3,3V, wobei die (meisten) Eingänge 5V tolerant sind. Deshalb ist 
es am AVR kein Problem, der liefert dann auch die 5V an Reset.

Vielen Dank für die Vorschläge!

Gruß
Johannes

von Johannes S. (jhs)


Lesenswert?

Hi!

Hmm, den Pull-up heute reingelötet, dazu eine sehr lange Reset-Sequence 
eingefügt, aber ich komm aus dem Busy-Status immer noch nicht raus. Was 
anzeigen geht dementsprechend auch nicht.

Vielleicht hat noch jemand eine Idee, ansonsten werd ich weiter 
Datenblatt lesen...

Danke,
Johannes

von nop (Gast)


Lesenswert?

A. K. schrieb:
>offiziell NOP.W

Super, herzlichen Dank.
Kann ich direkt brauchen (für eine kleine Verzögerung bei einem 
Chipselect).

von Johannes S. (jhs)


Lesenswert?

Hi!

Markus Müller schrieb:
> An Pin19 gehört sicher noch ein Vorwiderstand. Besser ist Pin19 an +5V,
> Pin20 mit Widerstand sind Transistor, den gesteuert mit einem
> Timer-Ausgang. Dann kann man das Display auch dimmen mit PWM.

Nur so nebenbei: Ja, wer lesen kann ist klar im Vorteil...

Natürlich steht im Datenblatt unter Note 4 auch die der Strom für den 
LED-Beleuchtung (250mA). Hab nen Widerstand eingefügt, auch wenn es mit 
dem eigentlich Problem nicht so viel zu tun hatte...

Danke,
Johannes

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Angehängte Dateien:

Lesenswert?

Probiere doch mal die Ausgabe im ms Raster (über Timer) aus zu geben.
Einfach die Befehle in einen FOFI Buffer rein schreiben, der Timer 
arbeitet die Ausgabe dann schon ab.
Ich meine ohne das Busy-Bit abzufragen.
Diese FIFO Variante hat ja auch den Vorteil, dass man im Code nicht 
warten muss und die Applikation garantiert weiter arbeitet.

Ich steuere die EADOG Displays alle über SPI Bus an, braucht weniger 
Leitung, dafür kann ich nichts aus dem Display lesen, auch kein Busy 
Flag, und funktioniert auch. (Ist halt ein einfaches 2x16 Zeichen 
Display) SPI kann leider dieser Samsung nicht.
Ausserdem haben die EADOGs auch den Vorteil direkt mit 3,3V klar zu 
kommen. Der hat zwar einen Display-Teil der 5V braucht, kann die aber 
selbst erzeugen. Ich schließe die so an, dass die 
Display-Controller-Einheit mit 3,3V und die LCD Einheit mit 5V betrieben 
wird. Dann kann ich den Spannungsdoppeler aus lassen.
Hat zwar nichts mit dem aktuellen Problem zu tun, aber vieleicht hilfts.

von Johannes S. (jhs)


Lesenswert?

Hi!

Nur zum Abschluss - da stehen so zwei kleine Zahlen an den enden der 
Pinleiste - nämlich 1 und 20. Und wenn man alles richtig rum anschließt 
geht's auch... duck

Das mit dem Timer hab ich allerdings trotzdem gemacht, blockierende 
Routienen kann ich gar nicht brauchen...


Gruß
Johannes

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Da musst Du blos die Pins vom Display umbiegen und das Display verkehrt 
herum einbauen, dann passt die Pinbelegung wieder ;-)

von Johannes S. (jhs)


Lesenswert?

Hi Markus!

Naja, genialerweise liegen bei dem Display ja auf 1,2 sowie auf 19,20 
GND und 5V, d.h. es fällt einfach nicht auf, dass es genau verkehrt 
herum ist. Allerdings werd ich mir trotzdem ein Kabel machen, dass alles 
wieder tauscht (und die nächste Platine richtig...), weil es etwas blöd 
ist, dass D0-D7 jetzt natürlich genau umgekehrt auf dem PORT liegen und 
ich alles immer umrechnen muss. Aber jetzt kann ich wenigstes schonmal 
testen.

Aber was solls, es geht. Hab viel über den Controller gelernt und 
nächste Woche kann ich dann auch anfangen meine Arbeit zu machen...

Danke nochmal für die Hilfe!

Johannes

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Bits drehen, dafür hab ich was:
1
// Bits drehen
2
u32 revbit32(u32 uidata)
3
{
4
  asm("rbit r0,r0");
5
  return uidata;
6
};

der Assembler-Befehl rbit macht 32 Bit.

von doc (Gast)


Lesenswert?

Markus Müller schrieb:
> der Assembler-Befehl rbit macht 32 Bit.

Dafür würde ich dann aber lieber die passende Fkt aus dem CMSIS nehmen:

uint32_t __RBIT(uint32_t value)

Ok, die ist auch in Assembler.
Da ist übrigens noch mehr nützliches drin :-) Reinschauen lohnt sich.

von Johannes S. (jhs)


Lesenswert?

Hi!

Würde dann aber wohl insgesamt auf das rauslaufen:
1
uint8_t data = QUEUE_Pop(&queue);
2
uint32_t rdata = __RBIT(data);
3
data = (uint8_t) (rdata >> 24);

Oder sehe ich das grad falsch? Aber an sich zum Testen keine schlechte 
Idee, in der endgültigen Fassung kann ich es dann hoffentlich 
rausnehmen!

Gruß
Johannes

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ja, genau.

Mein letztes Projekt mit einem STM32. Hast Du vielleicht bereist 
gesehen:
Beitrag "Re: Heizungssteurung im Eigenbau"
Schaltplan ist auch dabei.

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.