Forum: Mikrocontroller und Digitale Elektronik LCD von Pollin


von Micro (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche aktuell das 128x64 Display von Pollin in Betrieb zu nehmen.

Dabei habe ich mich auch an diesem älteren Thread orientiert:
Beitrag "[Pollin] Grafik Display Anschluss Verständnisfragen"


Als Controller möchte ich ein STM32MinDevBoard verwenden:
https://www.watterott.com/de/STM32F103C8T6-Minimum-System-Board

Der von mir verwendete Stromlaufplan ist angehangen.
Meinen Quellcode poste ich unten.
Die Datenleitungen sind als Open-Drain konfiguriert.


1. Funktioniert der Aufbau mit 3.3V DC GPIO's? Das Datenblatt des NT7538 
definiert die Logicgrenzen bei Low - 0.2*VDD und High - 0.8*VDD. Da VDD 
mit 1.8 - 3.6V DC angegeben ist würde ich davon ausgehen, dass das mit 
dem STM funktioniert?


2. in dem verlinkten Beitrag wird im letzten Post der 8080 Modus 
benannt. Kann jemand die Verwendung dessen Bestätigen? Mit der 
Beschriftung im Datenblatt wäre ich ehr von dem 6800-Modus ausgegangen. 
Der entsprechende Port vom LCD-Controller ist ja leider nicht 
zugänglich.


3. Hat jemand funktionierenden Quellcode den er mir zur Verfügung 
stellen kann um ihn mit meinem zu vergleichen? Ich habe die Schaltung 
per Breadboard aufgebaut. Auch wenn ich sie mehrfach aufgebaut habe 
traue ich diesen Steckbrettern doch nur bedingt über den Weg.


Liebe Grüße und danke fürs lesen ;)



Main:
1
uint8_t data = 0;
2
3
  //Reset
4
  HAL_GPIO_WritePin(NRESET_GPIO_Port, NRESET_Pin, GPIO_PIN_SET);
5
  HAL_Delay(500);
6
  HAL_GPIO_WritePin(NRESET_GPIO_Port, NRESET_Pin, GPIO_PIN_RESET);
7
  HAL_Delay(500);
8
  HAL_GPIO_WritePin(NRESET_GPIO_Port, NRESET_Pin, GPIO_PIN_SET);
9
  HAL_Delay(500);
10
11
12
  // function setup 11 LCD Bias
13
  Write_CMD(0xA2);
14
  // function setup  8 ADC selection
15
  Write_CMD(0xA0);
16
  // function setup 15 common output state
17
  Write_CMD(0xC0);
18
19
  // function setup 17 built in resistenc value
20
  Write_CMD(0x27);
21
  // function setup 18 electronic volume control
22
  Write_CMD(0x81);
23
  //Write_CMD(0x0F);
24
  Write_CMD(0x20);  //->not used
25
26
  // function setup 16 power control
27
  Write_CMD(0x2F);
28
29
  // function setup 25 display duty and bias
30
  Write_CMD(0x34);
31
  Write_CMD(0x3D);
32
33
34
  // 2
35
  Write_CMD(0x20 + 0);
36
  // 3
37
  Write_CMD(0xB0 + 0);
38
  // 4
39
  Write_CMD(0x00 + 0);
40
41
  // 6
42
  for(int i= 0; i<20; i++){
43
    Write_Data(0xFF);
44
  }
45
46
  // 1 turn Display ON
47
  Write_CMD(0xAF);
48
  data = Read_Status();

Helper-Functions
1
void Write_CMD(uint8_t var_cmd){
2
  HAL_GPIO_WritePin(A0_GPIO_Port, A0_Pin, GPIO_PIN_RESET);
3
  HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_RESET);
4
  Data_Set(var_cmd);
5
6
  //delay
7
  HAL_Delay(1);
8
9
  HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_RESET);
10
  HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_SET);
11
12
  //delay
13
  HAL_Delay(1);
14
15
  HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_RESET);
16
  HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_SET);
17
}
18
19
void Write_Data(uint8_t var_cmd){
20
  HAL_GPIO_WritePin(A0_GPIO_Port, A0_Pin, GPIO_PIN_SET);
21
  HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_RESET);
22
  Data_Set(0x55);
23
24
  //delay
25
  HAL_Delay(1);
26
27
  HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_RESET);
28
  HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_SET);
29
30
  //delay
31
  HAL_Delay(1);
32
33
  HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_RESET);
34
  HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_SET);
35
}
36
37
38
uint8_t Read_Status(){
39
  uint8_t data = 0;
40
41
    HAL_GPIO_WritePin(A0_GPIO_Port, A0_Pin, GPIO_PIN_RESET);
42
    HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_SET);
43
    Data_Release();
44
45
    //delay
46
    HAL_Delay(1);
47
48
    HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_RESET);
49
    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_SET);
50
51
    //delay
52
    HAL_Delay(1);
53
54
    data = Data_Read();
55
56
    HAL_Delay(1);
57
    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_RESET);
58
    HAL_GPIO_WritePin(NCS1_GPIO_Port, NCS1_Pin, GPIO_PIN_SET);
59
60
    return data;
61
  }
62
63
void Data_Set(uint8_t var_Data){
64
  HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, (var_Data>>7)&0x01);
65
  HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, (var_Data>>6)&0x01);
66
  HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, (var_Data>>5)&0x01);
67
  HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, (var_Data>>4)&0x01);
68
  HAL_GPIO_WritePin(D3_GPIO_Port, D3_Pin, (var_Data>>3)&0x01);
69
  HAL_GPIO_WritePin(D2_GPIO_Port, D2_Pin, (var_Data>>2)&0x01);
70
  HAL_GPIO_WritePin(D1_GPIO_Port, D1_Pin, (var_Data>>1)&0x01);
71
  HAL_GPIO_WritePin(D0_GPIO_Port, D0_Pin, (var_Data>>0)&0x01);
72
}
73
74
void Data_Release(void){
75
  HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, GPIO_PIN_SET);
76
  HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, GPIO_PIN_SET);
77
  HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, GPIO_PIN_SET);
78
  HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, GPIO_PIN_SET);
79
  HAL_GPIO_WritePin(D3_GPIO_Port, D3_Pin, GPIO_PIN_SET);
80
  HAL_GPIO_WritePin(D2_GPIO_Port, D2_Pin, GPIO_PIN_SET);
81
  HAL_GPIO_WritePin(D1_GPIO_Port, D1_Pin, GPIO_PIN_SET);
82
  HAL_GPIO_WritePin(D0_GPIO_Port, D0_Pin, GPIO_PIN_SET);
83
}
84
85
uint8_t Data_Read(void){
86
  uint8_t value = 0;
87
88
  value += HAL_GPIO_ReadPin(D7_GPIO_Port, D7_Pin)<<7;
89
  value += HAL_GPIO_ReadPin(D6_GPIO_Port, D6_Pin)<<6;
90
  value += HAL_GPIO_ReadPin(D5_GPIO_Port, D5_Pin)<<5;
91
  value += HAL_GPIO_ReadPin(D4_GPIO_Port, D4_Pin)<<4;
92
  value += HAL_GPIO_ReadPin(D3_GPIO_Port, D3_Pin)<<3;
93
  value += HAL_GPIO_ReadPin(D2_GPIO_Port, D2_Pin)<<2;
94
  value += HAL_GPIO_ReadPin(D1_GPIO_Port, D1_Pin)<<1;
95
  value += HAL_GPIO_ReadPin(D0_GPIO_Port, D0_Pin)<<0;
96
97
  return value;
98
}

von Karl M. (Gast)


Lesenswert?

Micro schrieb:
> 128x64 Display von Pollin

was steht denn/ die im Datenblatt/-er zu dem Display?

Dort sollte man fast alle Frage selbst klären können.

Und ohne wird es schwierig.

von Micro (Gast)


Lesenswert?

Hi Karl,

danke für die schnelle Antwort.

Die erste Frage meine ich mit den Datenblättern beantworten zu können. 
Das ist denke der Fragestellung auch schon zu entnehmen.

Die anderen beiden Fragen lassen sich mit den zur Verfügung stehenden 
Unterlagen nicht beantworten.

Deshalb ja meine Hoffnung, hier eventuell einen nützlichen Hinweis bzw. 
funktionierenden Code zum Vergleichen zu bekommen.

von NichtWichtig (Gast)


Lesenswert?

Laut Schaltplan ist das LCD unvollständig verdrahtet.
Grad mal die Datenleitungen sind dran.
Die restlichen Pins sind nicht ganz so unnützt wie manch einer meint.

Und für gewöhnlich ist aus dem Datenblatt glasklar zu entnehmen wie man 
die Pixel aktiviert.

von NichtWichtig (Gast)


Lesenswert?

Ach, P3 ist garnicht das 20polige Display, tschuldigung, ich habs mit 
meiner eigenen aktuelle Baustelle verwechselt.

von Axel S. (a-za-z0-9)


Lesenswert?

Micro schrieb:
> Die Datenleitungen sind als Open-Drain konfiguriert.

Das klingt falsch. Ich sehe da nirgends Pullups.
Wie soll das Display jemals einen H-Pegel sehen?


> Funktioniert der Aufbau mit 3.3V DC GPIO's?

Ich nehme an, daß du das Display mit den 3.3V vom STM versorgst. In dem 
Fall passen die Logikpegel. Nur daß du die Ausgänge am STM als push-pull 
konfigurieren mußt.

von Micro (Gast)


Lesenswert?

NichtWichtig schrieb:
> Grad mal die Datenleitungen sind dran.

Wenn ich etwas falsch verdrahtet habe nehme ich die Kritik gern an. Nur 
leider sehe ich in diesem Fall nicht was fehlt. Neben den 8 
Datenleitungen (zu P3) sind genauso die 5 Steuerleitungen und die 
Spannungsversorgung (zu P4) verbunden. Die 5xBoostschaltung (X1-17 bis 
X1-21) sowie die Kondensatoren zur Spannungsstabilisierung sind dran.

P3 und P4 sind als Pinheader zu verstehen, die direkt auf Pinheader des 
STM32MinDevBoard gesteckt werden.

von Micro (Gast)


Lesenswert?

Axel S. schrieb:
> Das klingt falsch. Ich sehe da nirgends Pullups.
> Wie soll das Display jemals einen H-Pegel sehen?

Die Pullups sind über STM32CubeMX direkt vom STM32F103 gesetzt, 
allerdings nur an den Datenleitungen. Diese sind, wie erwähnt, als 
Open-Drain konfiguriert. Alle anderen GPIOs sind als Push-Pull 
konfiguriert.

von Micro (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal die Konfiguration aus dem CubeMX. Damit sollte die 
GPIO-Konfiguration klar sein.

von W.S. (Gast)


Lesenswert?

Also eigentlich war damals (2017) schon alles zum Display gesagt. Wenn 
du den Thread gelesen hast, dann weißt du genug, um das Display benutzen 
zu können.

Aber wenn ich sowas sehe:

Micro schrieb:
> Main:.....

dann kommt mir der Groll. Warum machst du deine Bastelei denn nicht 
systematisch?

Also alles, was du da in main() hineingeschrieben hast, fliegt raus. In 
main gehören niedere Hardware-Angelegenheiten nicht hinein.

Stattdessen sehe ich für dein Vorhaben 4 separate Quellen:

1. Chip-Konfiguration, wo eben auch die diversen Pins zum Display 
eingerichtet werden. Also GPIO, rein oder raus, hier garantiert kein 
OpenDrain, sondern normale Ausgänge.

2. Lowlevel-Funktionen: Datenbyte setzen bzw. lesen, CS, A0, RES, R/W, E 
hi oder lo setzen.

3. der eigentliche Display-Treiber: Display initialisieren, ablöschen, 
Blocktransfer vom Displayram ins Display, ggf. Helligkeit und Kontrast 
einstellen, Orientierung setzen usw. Dieser Treiber stützt sich auf Nr. 
2, also die LL-Funktionen und deshalb sind dort keine 
plattformspezifischen Elemente mehr drin!

4. ein GDI: Text in den Displayram zeichnen, Punkte, Linien, Flächen 
zeichnen, Fonts verwalten, usw. Auch hier gibt es nichts 
plattformspezifisches.

So, wenn du dich daran hältst und dir nicht main() mit irgendwelchen 
HAL_GPIO_xyz zumüllst, dann wird es auch für dich einfacher. Denn du 
kannst immer schön der Reihe nach zu allererst nachprüfen, ob deine 
Pinkonfiguration stimmt, ob die Ansteuerung deiner Strippen zum Display 
stimmen, ob der eigentliche Displaytreiber stimmt und dann ob deine 
Routinen zum Malen auf dem LCD stimmen.

Eben immer der Reihe nach.
Das macht es den anderen Forenteilnehmern auch leichter, ggf. dir zu 
helfen. Ich zumindest werde mich definitiv NICHT durch ellenlange 
HAL_XYZ-Wüsten durchkämpfen.

W.S.

von W.S. (Gast)


Lesenswert?

Nochwas:

Micro schrieb:
> void Data_Set(uint8_t var_Data){
>   HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, (var_Data>>7)&0x01);
>   HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, (var_Data>>6)&0x01);
>   HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, (var_Data>>5)&0x01);
>   HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, (var_Data>>4)&0x01);
>   HAL_GPIO_WritePin(D3_GPIO_Port, D3_Pin, (var_Data>>3)&0x01);
>   HAL_GPIO_WritePin(D2_GPIO_Port, D2_Pin, (var_Data>>2)&0x01);
>   HAL_GPIO_WritePin(D1_GPIO_Port, D1_Pin, (var_Data>>1)&0x01);
>   HAL_GPIO_WritePin(D0_GPIO_Port, D0_Pin, (var_Data>>0)&0x01);
> }

Schaue ins Referenzmanual deines STM32F103C8T6 hinein und lerne, die 
Register

GPIOx_BSRR

zu benutzen.

W.S.

von Micro (Gast)


Lesenswert?

Hallo W.S.,

ja du hast recht das man einer Software eine Struktur geben muss, keine 
Frage. Dazu gibt es aber diverse Entwicklungsansätze die alle Ihre 
Richtigkeit haben. Ich zum Beispiel entwickel lieber bottum-up.

Wenn ich in die einzelnen Register schreiben wollen würde hätte ich das 
auch gemacht. Ich benutze aber mit Absicht die HAL, weil es zum einen 
praktischer und viel schneller geht, zum anderen erhält mir die 
Ansteuerung jedes einzelnen Pins ein hohes Maß an Flexibilität in der 
Hardware. Ich bin hier nicht gezwungen alle Datenleitungen auf einen 
Port zu legen und dabei auch noch die erste Datenleitung auf den ersten 
Pin usw.


Und da ich die Fragen nicht ohne Grund gestellt habe wäre es super, wenn 
man sich wieder darauf konzentrieren könnte.

von NichtWichtig (Gast)


Lesenswert?

Kann man so machen, sieht aber K***e aus.

W.S. hat das schon gut getroffen.

von Axel S. (a-za-z0-9)


Lesenswert?

Micro schrieb:
> Axel S. schrieb:
>> Das klingt falsch. Ich sehe da nirgends Pullups.
>> Wie soll das Display jemals einen H-Pegel sehen?
>
> Die Pullups sind über STM32CubeMX direkt vom STM32F103 gesetzt,
> allerdings nur an den Datenleitungen. Diese sind, wie erwähnt, als
> Open-Drain konfiguriert.

Aber warum? Wenn du auf das Display schreibst, muß der STM die Leitungen 
treiben, die Pins müssen also als Ausgang konfiguriert sein. Wenn du vom 
Display lesen willst (am ehesten wohl den Status) dann müssen die Pins 
am STM als Eingänge konfiguriert sein. Open Drain bringt als Ausgang 
keinen Vorteil (gegenüber Push-Pull) und ist nur dann als Eingang 
tauglich, wenn du jeden Pin auf H setzt.

Wenn du vom Display auch lesen können willst (das sparen sich viele 
LCD-Libraries) dann mußt du die Datenrichtung der Pins für den Datenbus 
zur Laufzeit umschalten. CubeMX unterstützt das nicht? Dann lerne halt, 
wie du direkt auf die Register der GPIO zugreifst. Das geht nicht nur 
schneller, sondern ist im Zweifelsfall sogar besser lesbar.

Mach es doch einfach wie der Rest der Welt (vulgo: richtig) und versuche 
nicht irgendwelche Sondergeschichten, die du nicht mal begründen kannst.

von Micro (Gast)


Lesenswert?

Axel S. schrieb:
> dann müssen die Pins
> am STM als Eingänge konfiguriert sein.

Das ist falsch. Die Register für Input- und Outputregister sind 
eigenständig und das auch schon viele viele Jahre.


Axel S. schrieb:
> nur dann als Eingang
> tauglich, wenn du jeden Pin auf H setzt.

in etwa so wie es in der Funktion "void Data_Release(void)" geschieht?


Axel S. schrieb:
> dann mußt du die Datenrichtung der Pins für den Datenbus
> zur Laufzeit umschalten.

falsch, ich muss nur eine Open-Drain-Schaltung verwenden.


Axel S. schrieb:
> Mach es doch einfach wie der Rest der Welt (vulgo: richtig) und versuche
> nicht irgendwelche Sondergeschichten, die du nicht mal begründen kannst.

Open-Drain ist keine Sondergeschichte sondern eine vollkommen normale 
Geschichte. Selbst auf Wikipedia ist wunderbar nachzulesen was diese 
Schaltung bewirkt.




Fazit: vielen Dank, ich weiß jetzt wieder wieso ich dieses Forum nicht 
mehr benutzen wollte. Anstatt nur dann eine Antwort zu geben wenn man 
sich für das Problem interessiert gibt es eine ganze Reihe von "Profis" 
die entweder eine Ansammlung von "ich weiß alles besser und du bist 
doof" zum besten geben oder einfach nur falsche Behauptungen in den Raum 
werfen ....


Der Thread kann gern gelöscht werden ....

von Axel S. (a-za-z0-9)


Lesenswert?

Micro schrieb:
> vielen Dank, ich weiß jetzt wieder wieso ich dieses Forum nicht
> mehr benutzen wollte

Bitte tu das. Jetzt gleich.

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.