Hallo,
ich versuche seit geraumer Zeit etwas auf einem LCD mit dem Controller
ST7920 auszugeben. Leider ohne Erfolg!
Hat jemand Erfahrung mit diesem Controller?
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.
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
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.
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?
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?
#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
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
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.
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...
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.
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.
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
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!
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)
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.
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'.
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 ' '
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.
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!
> 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"?
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?
>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.
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
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang