C Zeichnen mit einem GLCD

Sinniger ist es, den anzuzeigenden String als ... String, zu speichern, und die Muster bei Bedarf direkt aus der Zeichensatztabelle zu laden.
Jepp, das erhöht den Schwierigkeitsgrad aber noch mal um einige Stufen.

Dafür muß man die Zeichenausgabefunktion dahingehend anpassen (oder neu schreiben), daß sie nicht nur zeichenweise ausgeben kann, sondern an jeder Spaltenposition des Zeichens beginnend. Die Schrift soll ja wohl nicht zeichenweise sondern spaltenweise laufen. Da ist das mit dem buffer einfacher.

Und die beiden Punkte, die ich noch offengelassen habe sind schon garnicht mal so trivial. ;)
 
Oh, jetzt erst gesehen:


CodeBox C
strcpy((char*)buff,(const char*)msg);
Das kopieren der reinen ASCII-Zeichen in den buffer kannst Du Dir sparen, das bringt keine Vereinfachung.
Rate mal, warum der buffer strlen(msg) * CHARWIDTH groß ist.

Vielleicht hatte ich es undeutlich ausgedrückt:
Die Zeichen sollen so wie sie auf dem Display ausgegeben werden in den buffer geschrieben werden, also bei einen 5x7 Font wären das 6 Bytes für jedes ASCII-Zeichen.
Und dann werden 128 Bytes aus dem buffer in einem Rutsch in eine page des Display-RAM kopiert.
 
Vielleicht hatte ich es undeutlich ausgedrückt:
Die Zeichen sollen so wie sie auf dem Display ausgegeben werden in den buffer geschrieben werden, also bei einen 5x7 Font wären das 6 Bytes für jedes ASCII-Zeichen.
Und dann werden 128 Bytes aus dem buffer in einem Rutsch in eine page des Display-RAM kopiert.

Den Zeichensatz den Ich nutze ist 8x6. Das heißt also für ein Zeichen brauche ich 6 Bytes...
Ist es denn mit den Funktionen die wir bis jetzt hier gesehen haben möglich das zu realisieren was Ich vor habe?



CodeBox C
char msg[] = "Hallo Welt!";

Das heißt ich bräuchte hierfür schon 11*6 = 66 Bytes?
 
Eine Funktion, die die Zeichen in den buffer schreibt, fehlt auch noch.
Ist strcpy nicht die Funktion, die meine Message in den "buffer" rein schreibt?

Oder meinst du eine, die aus meinem "charSetArray" die einzelnen Bytes in den "buffer" schreibt?
 
Zuletzt bearbeitet:
Ist strcpy nicht die Funktion, die meine Message in den "buffer" rein schreibt?
Wie ich oben schon schrieb, kopierst Du damit nur die ASCII-Zeichen und nicht die 6 Bytes, die es braucht um das Zeichen auf dem Display anzuzeigen. Und das ist es, was im buffer stehen muß.
 
Wie ich oben schon schrieb, kopierst Du damit nur die ASCII-Zeichen und nicht die 6 Bytes, die es braucht um das Zeichen auf dem Display anzuzeigen. Und das ist es, was im buffer stehen muß.
Meintest du sowas?


CodeBox C
char *ascToRaw(char *str, char buff[])
{
   uint16_t    index = 0;
   uint8_t    ascRawByte = 0;
   while(*str)
   {
       for(ascRawByte = 0; ascRawByte < 6 ; ascRawByte++)
       {
           buff[index++] = font4[*str][ascRawByte];
       }
       ++str;
   }
return buff;
}
 
Und die beiden Punkte, die ich noch offengelassen habe sind schon garnicht mal so trivial. ;)
Naja, wenn der Buffer in Form von 128 Bytes gegeben ist, die das Pixelmuster des Stringes beinhalten, kannst Du das auch einfach so machen:
Der (äußere)Zahler zählt von 0..255, bei jedem Schleifendurchlauf der inneren Ausgabeschleife (0..127) wird bei (äußerer + innerer Zähler) kleiner128 oder größer 255 0x00 ausgegeben, ansonsten Buffer(außerer Zähler - 128 + innerer Zähler).

Der Assemblerer vereinfacht sich die Abfrage >127 ?, indem er nach der Operation einfach das Negative-Flag prüft. Ebenso bei größer 255 -> da kommt das Carry.
Also kurz und knackig der Inhalt der inneren Schleife:
beide Zähler addieren (ADD)
0x00 in dasselbe Register laden (mit LDI)
bei N=0 zu Label1 springen (BRPL)
bei C=1 zu Label1 springen (BRCS)
128 vom Register abziehen (SUBI) -> das ist der Index in den Buffer
Byte aus dem Buffer laden (LD)
hier Label1:
Byte an Display senden

Sollte eigentlich sogar mit einem der drei Pointerregister gehen.
Ich zähle vier Takte wenn 0x00 und sieben Takte wenn was aus dem Buffer gesendet werden soll bis zum Aufruf der Senderoutine (wenn man den Buffer gut positionieren kann)
 
Zuletzt bearbeitet:
Zuletzt bearbeitet:
Ja.

Der buffer muß so lang sein, wie die Anzahl der Zeichen * Zeichenbreite.

Nee, funktioniert noch nicht so, wie ich grade dachte... o_O

Meinst du jetzt das jetzt allgemein auch die Sache mit den einzelnen Pixel im buffer?
 
Der buffer muß so lang sein, wie die Anzahl der Zeichen * Zeichenbreite.
inclusive führene und oder folgende Leerzeichen

Der äußere Zähler z läuft von 0 bis 128 + Bufferlänge
Der innere Zähler i läuft von 0 bis 128
Bei jedem Inkrementieren des inneren Zählers wird buffer[i + z] ausgegeben, wenn i + z > 128 oder <= Bufferlänge + 128 ist.

Keine Garantie, daß das so funktionert. ;)

Meinst du jetzt das jetzt allgemein auch die Sache mit den einzelnen Pixel im buffer?
Nein, ich meinte diese Schleife.
 
Zuletzt bearbeitet:
Kann das sein, daß man posts übersieht, wenn man grade schreibt und nach dem Abschicken nicht zurückscrollt?
Habe mehrmals gesehen, daß jemand auf meine Antwort nicht eingegangen ist, wenn kurz nach mir jemand anderes gepostet hat.
Und Deinen vorletzten post habe ich auch erst beim zurückscrollen gesehen.:hmmmm:
 
Zuletzt bearbeitet:
Der innere Zähler i läuft von 0 bis 128
Bei jedem Inkrementieren des inneren Zählers wird buffer[i + z] ausgegeben, wenn i + z > 128 oder <= Bufferlänge + 128 ist.

Keine Garantie, daß das so funktionert. ;)
Da wrd es doch weder von lnks nach rechts ausgegeben?
 
@Mikro23
Habe das mal nachgebaut.. Magst mal bitte drüber schauen..


CodeBox C
void glcdScrollText(char *msg)
{
 #define MAX_CHAR_DISPLAY 20
 #define FONT_CHAR_WIDTH  6
 #define ADD(x,y) x+y
 uint16_t msgLen = 0;
 char *msgBuff = NULL;
 msgLen = strlen((char*)msgBuff); 
 char buffer[msgLen * MAX_CHAR_DISPLAY];
 msgBuff = ascToRaw(msg,buffer);
 uint16_t x,y = 0;
 for (x = 0 ; x < (msgLen+128) ; x++)
 {
  for (y = 0 ; y < 128 ; y++)
  {
   if (ADD(x,y) > 128 || ADD(x,y) <= (msgLen+128))
   {
    glcdGotoXY(0,y);
    glcdPutc(*(msgBuff+(x+y)));   
   }
  }
 }
}
 
Zuletzt bearbeitet:


CodeBox C
#define ADD(x,y) (x+y)

Definemakros IMMER klammern!


CodeBox C
char buffer[msgLen * FONT_CHAR_WIDTH];



CodeBox C
 for (uint16_t z = 0 ; z < (msgLen * FONT_CHAR_WIDTH + 128) ; z++)  {
     // Hier muß die Displayposition auf Anfang der Zeile gesetzt werden
     for (uint8_t i = 0 ; i < 128 ; i++) {
          if ((ADD(z,i) > 128) || (ADD(z,i) <= (msgLen * FONT_CHAR_WIDTH + 128))) {
               glcdGotoXY(0,y); // ist hier überflüssig,
                           // die Column-Adresse wird von WriteData automatisch inkrementiert
               glcdPutc(*(msgBuff+(x+y)));   // *
          }
     }
}

* Wenn ich davon ausgehe, daß die Funktion glcdPutc() ein ASCII-Zeichen auf das Display schreiben soll, ist sie hier verkehrt. Hierher gehört WriteData.

Das wären die Unstimmigkeiten, die mir auf den ersten Blick aufgefallen sind.
 
* Wenn ich davon ausgehe, daß die Funktion glcdPutc() ein ASCII-Zeichen auf das Display schreiben soll, ist sie hier verkehrt. Hierher gehört WriteData.
Habe Ich natürlich geändert.

Nur passert nichts. Wenn Ich von rechts scrollen wll, wieso sollte er dann bei "0" anfangen? Da passt was nicht..
 
Und da sollte wahrschenlich "x+z" stehen?
Nach dem von mir geänderten Beispiel z+i.

Ich habe versucht x und y zu vermeiden, da sich beide Schleifen auf die Spalten, d.h. die x-Richtung beziehen. Wenn Du unbedingt x benutzen möchtest, könnte die äußere Laufvariable z.B. xa und die innere xi heißen. y wird hier garnicht gebraucht, da wir ja innerhalb einer Zeile bzw. Page bleiben.

Ich habe z.Zt. nicht die Möglichkeit, es auszuprobieren.
Wenn Du den kompletten neusten Stand Deines Codes hier posten würdest, könnte vielleicht auch noch jemand anderes mal rüberschauen...
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)