www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Partielles Löschen eines GLCD´s


Autor: Sven B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe vor ein Countdown auf einem gLCD auszugeben. Aber das nur 
nebenbei.
Zum Problem:
Ich habe ein grafisches Display, auf dem sich die angezeigten Werte 
(Zeit: hh:mm:ss) auf immer der gleichen Position ändern.
(z.B. 12:34:22 usw.)
Wenn der Countdown läuft, werden die alten Werte überschreiben, so daß 
man
nach Ablauf der Zeit nichts mehr erkennen kann, weil z.B. die 3 eine 1 
überschrieben hat. (pixelwirrwarr)
Wie kann ich am effektivsten die zuvor angezeigten Werte löschen (ohne 
daß der gesamte LCD gelöscht wird ) ???
Mein Ansatz war ein Rechteck, das im sekundentakt die alte Zeit 
verdeckt.

Hat Jemand eine bessere Lösung ????

Gruß

Autor: Maik Fox (sabuty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte einfach die alte Zeit nochmal mit weißen Pixeln zeichnen, 
bevor man die neue mit schwarzen zeichnet.

Autor: Sven B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok.

Das wäre schon mal besser (schneller) als ein Rechteckt.
Danke für den Vorschlag werde ich ausprobieren.

Weiß jemand wie man es auf der professionellen Ebene macht ???

Gruß

Autor: Maik Fox (sabuty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven B. wrote:
> Das wäre schon mal besser (schneller) als ein Rechteckt.

Das ist nicht unbedingt gesagt, das hängt von der Implementierung der 
jeweiligen Funktionen (Textausgabe, Rechteck löschen) ab.

Je nach dem ist die Rechteck-Variante in der Ausführungszeit schneller, 
weil weniger aufwendig. Das ist aber reine Spekulation.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hast Du denn für ne komische Zeichenausgaberoutine?

Die Routine schreibt einfach immer auf ein ganzes Zeichenfeld, z.B. 
12*8.
Also nicht nur die neuen Pixel auf Foreground setzen, sondern auch die 
nicht mehr benötigten auf Background setzen.


Peter

Autor: Sven B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider nicht Peter.

Die Routine, die ich nutze schreibt leider nur pixelweise die Zeichen 
auf dem Display.
Aber Du hast schon recht. Die Methode wäre natürlich die optimalste.
Quasi so wie auf einem alfanummerischen Display...
Diese Routine nutze ich zum Anzeigen der Werte.

CODE:
void lcd_putc(uint8_t* font,uint8_t chr)
{
  uint8_t x,page,bit,data,cnt=0;
  
  if (font_char_present(font,chr)==1)  // print only if letter is present in font
  {
    if ( ( (cursor_x + font_char_width(font,chr)) <128)  && ((cursor_y+font_char_height(font))<=64))  // only print leeter if it fits in screen
    {
      uint16_t offset= font_start_offset(font,chr);  // get the position of the first byte in font-array
      
      for(page=0;page<=(font_char_height(font)-1)/8;page++)  // write all pages(rows)
      {
        lcd_write_cmd(LCD_SET_PAGE|((cursor_y/8)+page),CHIP1|CHIP2);  // calc the current page

        if (cursor_x<64)  // set cursor to its poition (0 on the inactive controller so it can start directly on chip change)
        {
          lcd_write_cmd(LCD_SET_ADD|cursor_x,CHIP1);
          lcd_write_cmd(LCD_SET_ADD|0,CHIP2);
        }
        else
        {
          lcd_write_cmd(LCD_SET_ADD|(cursor_x-64),CHIP2);        
        }

        for (x=cursor_x;x<cursor_x + font_char_width(font,chr);x++)  //fill "pages"
        {
          data= pgm_read_byte(font+offset+cnt++);

          if ( page==font_char_height(font)/8)    
            data>>=8-(font_char_height(font)%8);  // if char height is bigger than 8 we have to remove some leading zeros
          
          #ifdef FASTTEXT                // this is much much faster than using set_pixel (see discription in header file)
          if (cursor_y%8==0 )
          {
            if (x<64)                
              lcd_write_data(data,CHIP1);            
            else                  
              lcd_write_data(data,CHIP2);          
          }
          else
          #endif
          {
            for (bit=0;bit<8;bit++)
            {
              if ((data&(1<<bit))!=0)
               lcd_set_pixel(x,cursor_y+page*8+bit,BLACK);
            }
          }
        }      
        
        #ifdef FASTTEXT
        if(cursor_y%8==0)
        {
          if (x<64)                
            lcd_write_data(0,CHIP1);            
          else                  
            lcd_write_data(0,CHIP2);        
        }
        #endif
      }      
      cursor_x += font_char_width(font,chr)+1;


    }
  }
}

Autor: Sven B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry. NAtürlich die...

void lcd_puts(uint8_t* font,char* string)
{while(*string)lcd_putc(font,*string++);}

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu der Sache wegen der Geschwindigkeit beim Rechteck-Löschen ein kleines 
Beispiel basierend auf einem T6963C-Controller.

Der Controller unterstützt das Setzen/Löschen einzelner Pixel. 
Gleichzeitig kann aber auch ein ganzes Byte geschrieben werden, also 
acht Pixel. Hier dürfte klar sein, dass ein Rechteck dann schneller mit 
der byteweisen Löscherei schneller ist, als die pixelweise Löscherei 
eines vorher gezeichneten Zeichens.
Wenn man dann die Schriftgröße so gewählt hat, dass sie immer in 
Byte-Blöcke passt, dürfte es von der Geschwindigkeit her das schnellste 
sein.

Es kommt also drauf an, wie man es implementiert. Die byteweise Lösung 
hat u.U. den Nachteil, dass man bei aufwendigen GUIs dann Sachen löscht, 
die nicht gelöscht werden sollen, es hat also alles Vor- und 
Nachteile...

Ralf

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein Beispiel aus meiner T6963-Library:

Ein 8*12 Font ist ideal, um byteweise auf das GLCD zu schreiben. Es 
werden dann nur 12 Bytes vom Flash in das GLCD geschrieben.
Dabei geht es garnicht anders, als daß das alte Zeichen komplett 
gelöscht wird.

void glcd_char_8x12( u16 addr, u8 val )
{
  u8 i;
  prog_uint8_t *p;

  addr += GRAPH_MEM;
  p = font8x12 + 12 * (val - ' ');

  for( i = 12; i; i-- ){
    glcd_addr( addr );
    glcd_byte( pgm_read_byte( p++ ));
    addr += GRAPH_X / 8;
  }
}



Peter

Autor: Sven B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun gut.

Ich werde Eure Vorschläge genauer unter die Lupe nehmen.

Danke für´s Erste.

Sven

Antwort schreiben

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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.