Hallo zusammen
Ich hoffe alle hatten/haben frohe Ostern.
Ich sitze nun seit stunden an einem Problem und habe den Faden
inzwischen komplett verloren.
Folgende Ausgangslage:
Es gibt ein Bytearray namens uint8_t ScreenBuffer[1024];
Dieser repräsentiert mein Display welches 128x64 Pixel hat.
Das Display ist in 8 Pages zu je 128Bytes aufgeteilt.
Also in etwa so:
P0 | | | |.... | | | |
P1 | | | |.... | | | |
.
.
.
P7 | | | |.... | | | |
Wobei ein | ein Byte ist. LSB ist oben MSB ist unten.
Genau so interpretiere ich auch mein Array.
Mein Font ist ebenfalls so orientiert, dass er mir die Fontdaten als
"stehendes byte" angibt. Somit wäre es ideal, wenn ich direkt das Byte
in meinen Buffer schreiben könnte. An eine beliebige x,und y stelle
natürlich.
Und hier beginnt das Problem.
Ich schaffe es nicht, das Byte auf eine elegante, vernünftige Art und
Weise in den Buffer zu schreiben. Weil ich irgendwie auf dem Schlauch
stehe. Wenn sich das Byte innerhalb einer Page befindet, ist es ja noch
ziemlich einfach.
Sobald es sich aber auf zwei pages aufteil, muss ich das alte Byte
auslesen, maskieren, die daten um den versatz schieben und mit dem alten
verodern und schreiben. Dann die zweite Page einlesen, maskieren, daten
schieben, verodern, schreiben.... Soviel zur theorie.
Es kann auch sein, dass man nur einen bestimmten Bereich des
Fontdatenbyte schreiben möchte, dann brauche ich eine Funktion, welcher
ich eine maske übergeben kann um zu wählen welche daten ich brauche.
Im Anhang ist mein Versuch es so zu lösen.
Leider klappt das nicht und ich blicke nicht mehr durch.
Ich hoffe jemand kann mir eine elegante Lösung vorschlagen oder Tipps
geben.
Danke schonmal.
@Holger Krähenbühl (holgerkraehe)
>Es gibt ein Bytearray namens uint8_t ScreenBuffer[1024];>Dieser repräsentiert mein Display welches 128x64 Pixel hat.>Das Display ist in 8 Pages zu je 128Bytes aufgeteilt.
Dann sollte man das aber auch so in der Definition wiederfinden,
uint8_t ScreenBuffer[8][128]
>Wobei ein | ein Byte ist.> LSB ist oben MSB ist unten.
???
>Ich schaffe es nicht, das Byte auf eine elegante, vernünftige Art und>Weise in den Buffer zu schreiben. Weil ich irgendwie auf dem Schlauch>stehe. Wenn sich das Byte innerhalb einer Page befindet, ist es ja noch>ziemlich einfach.
Wozu überhaupt die logische Einteilung in Pages? Sollte das nicht besser
zeilenweise orientiert sein? Bei 128 Spalten macht das 16 Bytes/Zeile.
Also so
uint8_t ScreenBuffer[64][16]
>Sobald es sich aber auf zwei pages aufteil, muss ich das alte Byte>auslesen, maskieren, die daten um den versatz schieben und mit dem alten>verodern und schreiben.
Ja.
>Ich hoffe jemand kann mir eine elegante Lösung vorschlagen oder Tipps>geben.
Vergiss die Pages. Sturkturiere das Array zeilenorientiert. Dann
übergibst man zur Zeichenausgabe die x/y Koordinaten und einen Zeiger
auf das auszugebende Zeichen. Durch die Zeilenorientierung ist es
einfach die Startzeile bzw. Adresse auszurechnen, denn die ist direkt
nutzbar ;-). Bei der Spalte muss man rechnen, aber auch das ist einfach.
Etwa so.
1
voidwrite_char(uint8_t*letter,uint8_tx,uint8_ty){
2
uint8_ti,shift,mask;
3
4
shift=x%8;
5
x=x&0x7;
6
mask=~(0xFF>>shift);
7
8
for(i=0;i<8;i++){
9
if(shift==0){// Zeichen exakt auf Bytegrenze, keine Maskierung nötig
10
ScreenBuffer[y+i][x]=letter[i]
11
}else{// Zeichen zwischen 2 Bytes, maskieren und verknüpfen
Vielen Dank Falk für deine Antwort.
Falk B. schrieb:> Wozu überhaupt die logische Einteilung in Pages? Sollte das nicht besser> zeilenweise orientiert sein? Bei 128 Spalten macht das 16 Bytes/Zeile.> Also so
Dies wäre mir auch lieber, das Problem ist, dass das Display mit Pages
arbeitet. SSD1306 Controller. Ich schreibe den Buffer mit dem DMA
automatisch per SPI zum Display. deshalb muss mein Buffer ebenfalls in
Pages orientiert sein. Oder übersehe ich hier gerade etwas?
Falk B. schrieb:> Bei der Spalte muss man rechnen, aber auch das ist einfach.> Etwa so.
Vielen Dank für dein Beispiel.
Ist das jetzt für ein Buffer mit Pages ala [8][128]?
Falk B. schrieb:
1
}else{// Zeichen zwischen 2 Bytes, maskieren und verknüpfen
@ Holger Krähenbühl (holgerkraehe)
>Dies wäre mir auch lieber, das Problem ist, dass das Display mit Pages>arbeitet. SSD1306 Controller. Ich schreibe den Buffer mit dem DMA>automatisch per SPI zum Display. deshalb muss mein Buffer ebenfalls in>Pages orientiert sein. Oder übersehe ich hier gerade etwas?
Ja. Man kann das auch trennen. Es ist ja im Endeffekt nur eine
Berechungsweise für Adressen. Die sollte man so legen, das die
Schreibzugriffe möglichst einfach und logisch erfolgen.
>Ist das jetzt für ein Buffer mit Pages ala [8][128]?
Nein, für [64][16]. Ich hab übersehen, daß du 7x12 Zeichen hast. Mein
Beispiel ist für 8x8 Zeichen. Aber das Prinzip bleibt gleich.
>Denn Man muss ja die Page und nicht die Column wechseln
Das mit den Pages sollte man vermeiden! Sonst wird es zuviel Chaos!
Falk B. schrieb:> Nein, für [64][16]. Ich hab übersehen, daß du 7x12 Zeichen hast. Mein> Beispiel ist für 8x8 Zeichen. Aber das Prinzip bleibt gleich.
Ich verwende sowieso unterschiedlich grosse und breite fonts.
Dehslab würde ich dort einfach die jeweilige breite auslesen und
verwenden.
Das mit den [64][16] verwirrt mich jetzt ungemein.
mir ist bewusst, dass es schlussendlich auch "nur" 1024bytes sind.
Und man damit einfach anderst auf die Daten zugreifen kann.
Jedoch erwartet das Display von mir die Bytes momentan wie im Bild im
Anhang dargestellt. (rot markierter Bereich)
Zuerst also 128Bytes für die erste Page.
Dann die nächsten für die zweite usw...
Ich sende mommentan mit dem DMA alle 1024Bytes in einem rutsch.
Deshalb bin ich nach meine Verständnis an die Pages gebunden oder nicht?
Wäre ich eventuell besser dran, wenn ich das DIsplay auf den Vertical
Mode umstellen würde?
Danke
@Holger Krähenbühl (holgerkraehe)
>Ich verwende sowieso unterschiedlich grosse und breite fonts.>Dehslab würde ich dort einfach die jeweilige breite auslesen und>verwenden.
Das macht die Sache aber nicht einfacher. Schreib erst einmal ein paar
Funktion für einen gegbenen Font. Wenn das alles läuft und du es
WIRKLICH verstanden hast, kannst du Funktionen für verschieden große
Fonts schreiben.
>Das mit den [64][16] verwirrt mich jetzt ungemein.
Das war eine Annahme von mir.
>mir ist bewusst, dass es schlussendlich auch "nur" 1024bytes sind.>Und man damit einfach anderst auf die Daten zugreifen kann.
??
Was soll man mit so einer Aussage anfangen? Willst du alles ala
Turingmaschine programmieren? Viel Spaß! ;-)
Der Sinn einer SINNVOLLEN Datenstruktur ist es ja eben, bestimmte
Datenzuordnungen verständlich zu machen und leicht auf die Daten
zugreifen zu können.
>Jedoch erwartet das Display von mir die Bytes momentan wie im Bild im>Anhang dargestellt. (rot markierter Bereich)>Zuerst also 128Bytes für die erste Page.>Dann die nächsten für die zweite usw...
Sicher, aber ich sehe da keinen nennenswerten Unterschied zu einer
linearen Adressierung ohne Pages.
>Deshalb bin ich nach meine Verständnis an die Pages gebunden oder nicht?
Oder nicht.
Was in dem Bild fehlt ist der Zusammenhang zwischen den Zeilen und den
Daten, denn dein LCD hat sicher nicht nur 8 Zeilen ;-)
>Wäre ich eventuell besser dran, wenn ich das DIsplay auf den Vertical>Mode umstellen würde?
Nein.