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ß
Man könnte einfach die alte Zeit nochmal mit weißen Pixeln zeichnen, bevor man die neue mit schwarzen zeichnet.
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ß
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.
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
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:
1 | void lcd_putc(uint8_t* font,uint8_t chr) |
2 | {
|
3 | uint8_t x,page,bit,data,cnt=0; |
4 | |
5 | if (font_char_present(font,chr)==1) // print only if letter is present in font |
6 | {
|
7 | if ( ( (cursor_x + font_char_width(font,chr)) <128) && ((cursor_y+font_char_height(font))<=64)) // only print leeter if it fits in screen |
8 | {
|
9 | uint16_t offset= font_start_offset(font,chr); // get the position of the first byte in font-array |
10 | |
11 | for(page=0;page<=(font_char_height(font)-1)/8;page++) // write all pages(rows) |
12 | {
|
13 | lcd_write_cmd(LCD_SET_PAGE|((cursor_y/8)+page),CHIP1|CHIP2); // calc the current page |
14 | |
15 | if (cursor_x<64) // set cursor to its poition (0 on the inactive controller so it can start directly on chip change) |
16 | {
|
17 | lcd_write_cmd(LCD_SET_ADD|cursor_x,CHIP1); |
18 | lcd_write_cmd(LCD_SET_ADD|0,CHIP2); |
19 | }
|
20 | else
|
21 | {
|
22 | lcd_write_cmd(LCD_SET_ADD|(cursor_x-64),CHIP2); |
23 | }
|
24 | |
25 | for (x=cursor_x;x<cursor_x + font_char_width(font,chr);x++) //fill "pages" |
26 | {
|
27 | data= pgm_read_byte(font+offset+cnt++); |
28 | |
29 | if ( page==font_char_height(font)/8) |
30 | data>>=8-(font_char_height(font)%8); // if char height is bigger than 8 we have to remove some leading zeros |
31 | |
32 | #ifdef FASTTEXT // this is much much faster than using set_pixel (see discription in header file)
|
33 | if (cursor_y%8==0 ) |
34 | {
|
35 | if (x<64) |
36 | lcd_write_data(data,CHIP1); |
37 | else
|
38 | lcd_write_data(data,CHIP2); |
39 | }
|
40 | else
|
41 | #endif
|
42 | {
|
43 | for (bit=0;bit<8;bit++) |
44 | {
|
45 | if ((data&(1<<bit))!=0) |
46 | lcd_set_pixel(x,cursor_y+page*8+bit,BLACK); |
47 | }
|
48 | }
|
49 | }
|
50 | |
51 | #ifdef FASTTEXT
|
52 | if(cursor_y%8==0) |
53 | {
|
54 | if (x<64) |
55 | lcd_write_data(0,CHIP1); |
56 | else
|
57 | lcd_write_data(0,CHIP2); |
58 | }
|
59 | #endif
|
60 | }
|
61 | cursor_x += font_char_width(font,chr)+1; |
62 | |
63 | |
64 | }
|
65 | }
|
66 | }
|
Sorry. NAtürlich die... void lcd_puts(uint8_t* font,char* string) {while(*string)lcd_putc(font,*string++);}
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
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.
1 | void glcd_char_8x12( u16 addr, u8 val ) |
2 | {
|
3 | u8 i; |
4 | prog_uint8_t *p; |
5 | |
6 | addr += GRAPH_MEM; |
7 | p = font8x12 + 12 * (val - ' '); |
8 | |
9 | for( i = 12; i; i-- ){ |
10 | glcd_addr( addr ); |
11 | glcd_byte( pgm_read_byte( p++ )); |
12 | addr += GRAPH_X / 8; |
13 | }
|
14 | }
|
Peter
Nun gut. Ich werde Eure Vorschläge genauer unter die Lupe nehmen. Danke für´s Erste. Sven
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.