Forum: Mikrocontroller und Digitale Elektronik GLCD Controller ST7920


von Bruno M. (brumay)


Lesenswert?

Hallo,
ich versuche seit geraumer Zeit etwas auf einem LCD mit dem Controller 
ST7920 auszugeben. Leider ohne Erfolg!
Hat jemand Erfahrung mit diesem Controller?

von Oliver S. (oliverso)


Lesenswert?

DaS Netz ist voll mit libs und Code dazu. Daher stellt sich die Frage, 
was du bisher probiert hast, und auch, womit?

Oliver

von Bruno M. (brumay)


Lesenswert?

Erst schon mal danke, daß du auf meine Frage reagierst.
Ganz so viele Codes sind im Netz nicht vorhanden und wenn dann nur in C, 
was mir nicht weiterhilft.
Probiert habe ich schon so ziemlich alles, aber ich scheine etwas noch 
nicht verstanden zu haben. Init und Commands sind kein Problem, aber ich 
bekomme keine Anzeige, außer dem Curser.
Mir ist nicht klar wie ich Zugriff bekomme auf die ASCII Bytes im 
HCGROM.
Nur den Curser setzen und 2 Bytes schreiben funktioniert nicht.

Ich kann natürlich auch gerne meine asm-Code-Schnipsel zeigen wenn das 
hilft.

von Oliver S. (oliverso)


Lesenswert?

Aha. Also kein C, und im Nebensatz steht was von ASM. Und das schon im 
zweiten Beitrag...

Vielleicht denkst du doch nocmal drüber nach, wie denn jemand was zu 
deiner Frage schreiben soll, wenn kein Mensch weiß, womit und worauf du 
da rumprogrammierst?

Oliver

von Bruno M. (brumay)


Lesenswert?

Meinen ersten Beitrag habe ich schon mit AVR ASM überschrieben, aber aus 
Erfahrung weiß ich, daß darauf kaum jemand reagiert.

Meine Fragen sind aber eigentlich unabhängig von der Programmiersprache, 
sondern betreffen die Interpretation des Datenblattes. Wenn dann noch 
jemand Interesse an meinem Code hat, dann natürlich umso besser.

von Christian S. (roehrenvorheizer)


Angehängte Dateien:

Lesenswert?

Hallo,

hier mal ein Codeschnipsel, leider nicht in ASm, aber es geht um das 
Verständnis:
(das Datenblatt nochmals zu studieren geht mit zu lange)

Beitrag "DG14032 Grafikdisplay und ST7920-Demo-Programm"

mfG

: Bearbeitet durch User
von Bruno M. (brumay)


Lesenswert?

Christian S. schrieb:
> hier mal ein Codeschnipsel

vom Prinzip her habe ich das auch x-mal so versucht. Der Teufel liegt 
sicherlich im Detail.

GLCD_Write(RS_CMD,CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)));

was bedeutet diese Zeile genau?
RS_CMD - heißt das RS setzen?
y*16+(x&0x1E) - ich nehme an y ist die Zeile und x die Spalte.
Wenn ich also die Startposition haben will, dann bleibt nur 0x1E weil x 
und y 0 sind. Ist das richtig?

von Bruno M. (brumay)


Lesenswert?

Ich habe mir den gesamten Code von DG14032 nochmals angesehen und kann 
meine Fragen teilweise selbst beantworten:

#define RS_CMD    0
#define CMD_SET_DDRAM_ADR  0x80

CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)) bedeutet bei x und y = 0: 0b10011110

richtig?

von Bruno M. (brumay)


Lesenswert?

> CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)) bedeutet bei x und y = 0: 0b10011110

stimmt nicht! Ich habe das & nicht berücksichtigt. Die Antwort ist also 
0x80

von Christian S. (roehrenvorheizer)


Lesenswert?

#define RS_DATA    1
#define RS_CMD    0  ist eine Konstante


static void RS (uint8_t val) {
  if (val) PORT_RS |= (1<<BIT_RS); else PORT_RS &= ~(1<<BIT_RS);
  }
setzt den RS-Ausgang bei 1 und löscht ihn bei 0
_______________________________

GLCD_Write(RS_CMD,CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)));

links des Kommas ist also 0; 0x80 bitweise verodert mit (( 16 mal y plus 
(x bitweise verundet mit 0x1E))

https://de.wikibooks.org/wiki/C-Programmierung:_Ausdr%C3%BCcke_und_Operatoren#Bitweises_UND_/_AND_&;

Bei Fehlern bitte korrigieren.

mfG

von Bruno M. (brumay)


Lesenswert?

also nochmals meine Frage:
CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)) bedeutet bei x und y = 0: 0x80

da #define CMD_SET_DDRAM_ADR  0x80

von Christian S. (roehrenvorheizer)


Lesenswert?

Bruno M. schrieb:
> also nochmals meine Frage:
> CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)) bedeutet bei x und y = 0: 0x80
>
> da #define CMD_SET_DDRAM_ADR  0x80

korrekt 0x80


mfG

von Bruno M. (brumay)


Lesenswert?

Dann gebe ich auf, denn so habe ich es immer gemacht.

Trotzdem danke für die Hilfe!

von Besserwisser (Gast)


Lesenswert?

Ich will nicht klugscheißen - so nur mal ein Gedankengang:
man könnte auch eine Arduino Lib nehmen und die Sequenzen aus den
cpp File entnehmen und weiter verwenden bzw. analysieren.
So wie ich das sehe,suchst/brauchst Du die Sequenzen um das
Display zum laufen zu bringen.
Auch kannst Du mit der Lib erst einmal testen ob die Hardware überhaupt 
läuft.
Aber wie gesagt nur mal so einen Idee - ich bin auch kein Profi.

von Hugo H. (hugohurtig1)


Lesenswert?

Hier hast Du mal einen Ansatz, wie man so etwas angehen kann - zwar für 
den "Standard HD44780" aber mit Datenblatt-Studium kann man timing und 
Befehle entsprechend umsetzen:

http://web.alfredstate.edu/faculty/weimandn/programming/lcd/ATmega328/LCD_code_asm_8ds.html

von John Doe (Gast)


Lesenswert?

Bruno M. schrieb:
> Ich kann natürlich auch gerne meine asm-Code-Schnipsel zeigen wenn das
> hilft.

Na, wo sind sie denn nun?

von John Doe (Gast)


Lesenswert?

Hugo H. schrieb:
> Hier hast Du mal einen Ansatz, wie man so etwas angehen kann - zwar für
> den "Standard HD44780" aber mit Datenblatt-Studium kann man timing und
> Befehle entsprechend umsetzen:
>
> 
http://web.alfredstate.edu/faculty/weimandn/programming/lcd/ATmega328/LCD_code_asm_8ds.html

Nett gemeint, aber:
1. Muss er kein "timing" umsetzen, da er SPI verwendet
2. Das Datenblatt des ST7920 ist eine lausig und missverständliche 
Übersetzung aus dem Chinesischen, also nichts so einfach zu lesendes wie 
der HD44780

Daher ist das schon ein bisschen herausfordernder...

von Bruno M. (brumay)


Lesenswert?

John Doe schrieb:
> Na, wo sind sie denn nun?
1
.equ LCD_Fun_Bas  = 0b00100000
2
3
.equ LCD_ON      = 0b00001100
4
.equ LCD_OFF    = 0b00001000
5
.equ LCD_Curser_ON  = 0b00001110
6
.equ LCD_Curser_OFF  = 0b00001100
7
.equ LCD_Blink_ON  = 0b00001111
8
.equ LCD_Blink_OFF  = 0b00001110
9
.equ LCD_SHIFT    = 0b00010100    ;Curser shifts right
10
11
.equ LCD_HOME    = 0b00000010
12
.equ LCD_Entry    = 0b00000110    ;Curser moves right
13
.equ LCD_CLEAR    = 0b00000001
14
15
.equ LCD_DDRAM_1  = 0b10000000    ;1. Zeile, jeweils Reihe 0 bis 7 (80H...87H)
16
.equ LCD_DDRAM_2  = 0b10010000    ;2. Zeile (90H...97H)
17
.equ LCD_DDRAM_3  = 0b10001000    ;3. Zeile (88H...8FH)
18
.equ LCD_DDRAM_4  = 0b10011000    ;4. Zeile (98H...9FH)
19
20
.equ LCD_Fun_Ext  = 0b00100100
21
.equ LCD_GDRAM_V  = 0b01000000
22
.equ LCD_GDRAM_H  = 0b01000000
23
24
;*******************************************************************************************
25
LCD_init:
26
  rcall  _Reset
27
  ldi    Daten, LCD_Fun_Bas      ;Basis Funktionen
28
  rcall  lcd_writecom
29
  rcall  delay100us
30
  ldi    Daten, LCD_Fun_Bas      ;Basis Funktionen
31
  rcall  lcd_writecom
32
  rcall  delay100us
33
  ldi    Daten, LCD_ON        ;Display an, Curser und Blinken aus
34
  rcall  lcd_writecom
35
  rcall  delay100us
36
  ldi    Daten, LCD_Clear      ;Display clear
37
  rcall  lcd_writecom
38
  rcall  delay50us
39
  ldi    Daten, LCD_Entry      ;Curser springt weiter und Adresszähler wird erhöht
40
  rcall  lcd_writecom
41
  rcall  delay50us
42
ret
43
44
;**************************************************************************************************
45
Ausgabe:
46
  rcall  _Reset
47
  ldi    Daten, LCD_DDRAM_1 
48
  rcall  lcd_writecom
49
  rcall  delay50ms
50
  ldi    Daten, 0
51
  rcall  lcd_writebyte
52
  rcall  delay50us
53
  ldi    Daten, 'A'
54
  rcall  lcd_writebyte
55
  rcall  delay50us
56
  ldi    Daten, 0
57
  rcall  lcd_writebyte
58
  rcall  delay50us
59
  ldi    Daten, 'B'
60
  rcall  lcd_writebyte
61
  rcall  delay50us
62
ret
63
64
;*************************************************************************************
65
;Ausgabe eines Befehls
66
lcd_writecom:
67
   ldi    temp, 0b11111000  ;11111-Synchronizing Bits, 0-RW, 0-RS, 0
68
  out    SPDR, temp
69
  rcall  Wait_Transmit
70
  push  Daten
71
  andi  Daten, 0b11110000
72
  out    SPDR, Daten      ;High nibble raus
73
  rcall  Wait_Transmit
74
75
  rcall  delay50us
76
  pop    Daten
77
  swap  Daten
78
  andi  Daten, 0b11110000
79
  out    SPDR, Daten      ;Low nibble raus
80
    rcall  Wait_Transmit
81
  rcall  delay50us
82
ret
83
84
;Ausgabe von Daten
85
lcd_writebyte:
86
  ldi    temp, 0b11111010  ;11111-Synchronizing Bits, 0-RW, 1-RS, 0
87
  out    SPDR, temp
88
  rcall  Wait_Transmit
89
  push  Daten
90
  andi  Daten, 0b11110000
91
  out    SPDR, Daten      ;High nibble raus
92
  rcall  Wait_Transmit
93
  
94
  rcall  delay50us
95
  pop    Daten
96
  swap  Daten
97
  andi  Daten, 0b11110000
98
  out    SPDR, Daten      ;Low nibble raus
99
    rcall  Wait_Transmit
100
  rcall  delay50us
101
ret

von Hugo H. (hugohurtig1)


Lesenswert?

John Doe schrieb:
> 1. Muss er kein "timing" umsetzen, da er SPI verwendet

Schwätzer - auch das HD44780 hat ein Timing, welches es einzuhalten 
gilt.

Es gibt massig Datenblätter in ordentlichem Englisch, z. B.

https://www.crystalfontz.com/controllers/Sitronix/ST7920/

wenn man so etwas nicht lesen kann hat man das falsche Hobby gewählt.

von John Doe (Gast)


Lesenswert?

Hugo H. schrieb:
> John Doe schrieb:
>> 1. Muss er kein "timing" umsetzen, da er SPI verwendet
>
> Schwätzer - auch das HD44780 hat ein Timing, welches es einzuhalten
> gilt.

Selber Schwätzer. Genau das meinte ich nämlich: Beim HD44780 muss man 
aufs Timing der einzelnen Pins achten, beim ST7920 nicht, wenn man SPI 
nutzt.

> Es gibt massig Datenblätter in ordentlichem Englisch, z. B.
>
> https://www.crystalfontz.com/controllers/Sitronix/ST7920/
>
> wenn man so etwas nicht lesen kann hat man das falsche Hobby gewählt.

Gelesen hast Du das Datenblatt sicher nicht, von unklaren Formulierungen 
bis hin zu dicken Fehlern ist da alles dabei.
Die vom HD44780, SSD1306, ILI9341, ST7735, etc. sind da deutlich 
einfacher zu lesen. Und wenn dann ein Einsteiger gleich so ein blödes 
Datenblatt bekommt, kann ich gut verstehen, dass er damit ein paar 
Schwierigkeiten hat.

von S. Landolt (Gast)


Lesenswert?

Wie kommt es zu diesem 'rcall delay50us', im Datenblatt steht doch bei 
fast jedem Befehl 'Exec time  72 us'?

von Dr. MCU (Gast)


Lesenswert?

Auch das
1
  rcall  delay50us

zwischen Highnibble und Lownibble in lcd_writecom und lcd_writebyte ist 
unnötig laut Datenblatt. Die 24 Bit/3 Byte werden am Stück rausgetaktet.

von Christian S. (roehrenvorheizer)


Lesenswert?

Für andere als die von mir angewandte Variante
"Grafik-LCD-Display DG14032  8-bit-Modus ausgewählt,", wie 4-Bit-Modus 
oder SPI kann der Code nicht passen.

mfG

von Bruno M. (brumay)


Lesenswert?

S. Landolt schrieb:
> Wie kommt es zu diesem 'rcall delay50us'

Ich habe eigentlich immer 100us (2 x 50us), da sowohl in der 
Ausgaberoutine als auch im Code 50us eingebaut sind.

Die Kommandos funktionieren auch völlig problemlos, das habe ich mit dem 
Curser mehrmals getestet. Sogar bei der Ausgabe der Bytes springt der 
Curser weiter. Es wird nur nichts angezeigt.
Inzwischen muß ich davon ausgehen, daß das Display eine Macke hat!

von S. Landolt (Gast)


Lesenswert?

Sehr wahrscheinlich haben Sie das bereits versucht, ich möchte es aber 
trotzdem angesprochen haben: was passiert, wenn statt $00 'A' und $00 
'B' ausgegeben wird: 'A' 'B' und 'C' 'D'? Mir ist die vorangestellte 
Null nicht klar.

(aber ohne die Hardware ist eben schlecht raten, dies war also mein 
zweiter&letzter Versuch)

von Bruno M. (brumay)


Lesenswert?

S. Landolt schrieb:
> Mir ist die vorangestellte
> Null nicht klar.

Laut Datenblatt sind die normalen fonts 16x16 bits. Zusätzlich gibt es 
aber half-width fonts (das sind die ASCII fonts). Auch wenn ich mit 
letzteren arbeiten will, muß ich immer 16x16 bits ausgeben.
Meine Version würde dann (Space)A(Space)B ausgeben und deine AABB.

von S. Landolt (Gast)


Lesenswert?

Habe ich noch nicht verstanden - "Space" soll $00 sein? Und im 
Datenblatt lese ich 'To display HCGROM fonts ... The data is among 
02H~7FH'; ich hätte naiv angenommen, dass dieses vorangestellte $00 das 
'CGRAM' anspricht: 'To display CGRAM fonts ... Only 0000H, 0002H, 0004H 
and 0006H are acceptable'.

von Bruno M. (brumay)


Lesenswert?

Ich fasse es nicht!!!!
Du hast recht.
Um ehrlich zu sein habe ich das von irgendwo übernommen, ohne ernsthaft 
darüber nachzudenken.

Space wäre natürlich ' '

von Bruno M. (brumay)


Angehängte Dateien:

Lesenswert?

Super, herzlichen Dank!

von Christian S. (roehrenvorheizer)


Lesenswert?

Toll! Es kommt AABB auf dem Display an. Das würde ich mich auch freuen.
Die Lösung ist trivial, den Weg, diese zu finden, allerdings nicht.

mfG

von Bruno M. (brumay)


Lesenswert?

Hallo,

ich muß mich noch einmal melden, u.z. hänge ich jetzt bei der Grafik.

Ich habe den Grafikmodus eingeschaltet und den Bildschirm geleert. So 
weit so gut.

Als nächstes wollte ich den Bildschirm komplett füllen. Wenn ich diesen 
Befehl unmittelbar nach dem Einschalten des Grafikmodus ausführe ist 
alles OK. Wenn ich aber zuerst leere und dann fülle, dauert es erstmal 
ewig bis er anfängt und dann wird die V-Adresse nicht auf 0 gestellt, 
sondern er macht erst die Zeile 31 und springt dann in die zweite Zeile. 
Im Ergebnis läßt er die Zeile 0 also immer aus.
Den gleichen Effekt habe ich auch wenn ich zuerst fülle und dann leere.
1
.equ LCD_Fun_Ext  = 0b00100100    ;Extended Function
2
.equ LCD_GRAPH_ON  = 0b00100110    ;Grafik ein
3
.equ LCD_GDRAM_V  = 0b10000000    ;0 bis 3F (63)
4
.equ LCD_GDRAM_H  = 0b10000000    ;0 bis F (15)
5
6
;************************************************************************************************
7
Home_GDRAM:
8
  ldi    Daten, LCD_GDRAM_V
9
  rcall  lcd_writecom        
10
  rcall  delay50us
11
  ldi    Daten, LCD_GDRAM_H
12
  rcall  lcd_writecom        
13
  rcall  delay50us
14
ret
15
16
;*******************************************************************************************************
17
Clear_GDRAM:
18
  rcall  _Reset
19
  ldi    temp1, 1          ;Zähler für vertikale Adresse
20
  rcall  Home_GDRAM
21
_Clear_GDRAM:
22
  clr    temp            ;Zähler für horizontale Adresse
23
Clear_GDRAM_loop:            ;Schleife zum löschen von 2 horizontalen Reihen (0 und 32, 1 und 33, 2und 34 usw.)
24
  ldi    Daten, 0x00
25
  rcall  lcd_writebyte
26
  rcall  delay50us
27
  rcall  lcd_writebyte
28
  rcall  delay50us
29
  inc    temp
30
  cpi    temp, 16
31
  breq  SET_H_Loop
32
  rcall  delay100ms
33
rjmp  Clear_GDRAM_loop
34
SET_H_Loop:                ;Schleife zum Weiterzählen der vertikalen Adresse
35
  ldi    Daten, LCD_GDRAM_V
36
  or    Daten, temp1        ;nächste V-Adresse
37
  rcall  lcd_writecom
38
  ldi    Daten, LCD_GDRAM_H
39
  rcall  lcd_writecom        ;H-Adresse auf 0
40
  rcall  delay50us
41
  inc    temp1
42
  cpi    temp1, 32
43
  breq  exit1
44
rjmp  _Clear_GDRAM
45
46
;*******************************************************************************************************
47
exit1:
48
ret
49
50
;*******************************************************************************************************
51
Fill_GDRAM:
52
  rcall  _Reset
53
  rcall  Home_GDRAM
54
  ldi    temp1, 1          ;Zähler für vertikale Adresse
55
_Fill_GDRAM:
56
  clr    temp            ;Zähler für horizontale Adresse
57
Fill_GDRAM_loop:            ;Schleife zum löschen von 2 horizontalen Reihen (0 und 32, 1 und 33, 2und 34 usw.)
58
  ldi    Daten, 0xFF
59
  rcall  lcd_writebyte
60
  rcall  delay50us
61
  rcall  lcd_writebyte
62
  rcall  delay50us
63
  inc    temp
64
  cpi    temp, 16
65
  breq  SET_H_Loop_Fill
66
  rcall  delay100ms
67
rjmp  Fill_GDRAM_loop
68
SET_H_Loop_Fill:            ;Schleife zum Weiterzählen der vertikalen Adresse
69
  ldi    Daten, LCD_GDRAM_V
70
  or    Daten, temp1        ;nächste V-Adresse
71
  rcall  lcd_writecom
72
  ldi    Daten, LCD_GDRAM_H
73
  rcall  lcd_writecom        ;H-Adresse auf 0
74
  rcall  delay50us
75
  inc    temp1
76
  cpi    temp1, 32
77
  breq  exit1
78
rjmp  _Fill_GDRAM

Hinweis: den delay 100ms habe ich eingefügt, damit ich den Ablauf 
beobachten kann.

von Bruno M. (brumay)


Lesenswert?

Nachtrag:
Wie ich soeben festgestellt habe, kann ich das Problem mit 2 
Home-Befehlen und einer dazwischen liegenden Dummy Ausgabe lösen. Was 
allerdings bleibt ist der extrem lange Zeitraum dazwischen.

Eine Erklärung ist das natürlich auch nicht!

von S. Landolt (Gast)


Lesenswert?

> dauert es erstmal ewig

Unklar - ich dachte, es erfolgt keinerlei Rückmeldung vom ST7920, dann 
läge es doch ausschließlich am Programm selbst: einfach die Schleifen 
durchzählen, oder im schlimmsten Fall das Programm in den Simulator 
stecken und diiesen zählen lassen. Falls nicht: an welcher Stelle wird 
auf die Rückmeldung gewartet?
  Allgemein ist es sicher unnötig, nach jedem Byte 50 us zu warten, die 
72 im Datenblatt gelten ja pro Befehl.
  Und was genau heißt "ewig"?

von Bruno M. (brumay)


Lesenswert?

S. Landolt schrieb:
> Und was genau heißt "ewig"?

Ich hatte schon alles ausgeschaltet, aber auf diese Frage hin habe ich 
es nochmals angemacht um es zu stoppen und siehe da jetzt ging es normal 
schnell. Vorher waren es geschätzt mindestens 30s.

Was mich aber eher beschäftigt ist die Frage, warum er auf den ersten 
Home Befehl nicht richtig reagiert. Stimmt vielleicht das timing nicht 
und wenn ja wo?

von S. Landolt (Gast)


Lesenswert?

>Stimmt vielleicht das timing nicht
Ich kann nur wiederholen: im Datenblatt steht 72 us nach einem Befehl, 
bei Ihnen sehe ich überall 50 us. Wohingegen das Warten zwischen Bytes 
eines Befehls unnötig ist.
  Da mir aber die Hardware fehlt, sollte ich mich verabschieden, es wird 
sonst zu einer reinen Raterei.

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

im Beispiel, das ich vor etlichen Jahren mir heraus gesucht habe, 
erfolgt ein dummy-read und danach wird zwei Mal gelesen. Wozu und warum 
ist mir ohne längeres Studium des Dablas und ohne mit dem Code zu 
experimentieren nicht mehr klar.

setzt einen Punkt auf im Grafikspeicher:
void GLCD_SetPixel(uint8_t x,uint8_t y, uint8_t color)
{
  uint8_t subpos;
  uint8_t pix;
  uint8_t pixel_low;
  uint8_t pixel_high;

  GLCD_SetExtendedMode();
  GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_VER&y)); 
//erstes Byte senden: vertikale Adresse 5 Bytes -->> 0..63; 0x80 = Bit7 
oder 0x3F = 11 1111,
  GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_HOR&(x>>4)));// 
als zweites Byte senden: die horizontale Adresse 0...15
  GLCD_Read(RS_DATA);
  pixel_high  = GLCD_Read(RS_DATA);
  pixel_low   = GLCD_Read(RS_DATA);

  subpos = x & 0x0F;                          //Maskieren: nur 0..15 
relevant
  GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_VER&y));
  GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_HOR&(x>>4))); 
//horizontal sind nur obere 4 Bits relevant

  if (subpos < 8) {
    pix = color ? (1<<(7-subpos))|pixel_high : 
(~(1<<(7-subpos)))&pixel_high;
    GLCD_Write(RS_DATA,pix);
    GLCD_Write(RS_DATA,pixel_low);
    }
  else {
    pix = color ? (1<<(15-subpos))|pixel_low : 
(~(1<<(7-subpos)))&pixel_low;
    GLCD_Write(RS_DATA,pixel_high);
    GLCD_Write(RS_DATA,pix);
    }

}

mfG

von Wolfgang W. (Gast)


Lesenswert?

Hallo,

ich habe den ST7920 bisher mal im seriellen Modus und mal im parallelen 
4-Bit-Modus (mit PIC16F18326) angesteuert.

Ohne Kenntnis des ST7920-Datenblatts ist man natürlich aufgeschmissen!

Da im seriellen Modus nur Schreiben und damit keine Statusabfrage 
möglich ist, muss man (vgl. S. Landolt) nach jedem Befehl besagtes Delay 
72 us einfügen. Im Worst case mit +/- 20% Clock-Abweichung sind das 
sogar ca. 85 us. Damit kommt man z.B. mit ca. 1100 Bytes für eine 
Grafikseite und 1-MHz Serial Clock bei 3 Bytes pro Befehl auf 110 ... 
120 ms Übertragungszeit pro 128x64-Grafikseite.

Im parallelen Modus mit Abfrage des Statusbits zeigt sich, dass nur 
wenige Bytes das volle Delay brauchen, sondern vor allem die Daten-Bytes 
schneller hintereinander übertragen werden. Ich habe im 4-Bit-Modus mit 
Oszi ca. 40 ms für eine Grafikseite gemessen. Im 8-Bit-Modus spart man 
nicht sehr viel, weil hauptsächlich dieses geforderte Delay die gesamte 
Übertragungszeit ausmacht.

Zum Textmodus ist zu sagen: durch seine eigentümliche Ansteuerung, die 
immer nur word-weise geht, müssen immer paarweise Character gesendet 
werden.

Wer sich aktiv mit ST7920- und/oder HD44780-Displays beschäftigt hat, 
weiss natürlich, dass Beide nicht vergleichbar sind.

MfG Wuff_W

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.