Announcement: there is an
English version of this forum on
EmbDev.net . Posts you create there will be displayed on Mikrocontroller.net
and EmbDev.net.
Anbei eine Beta meines Konverters.
Vorerst müsste das Exportieren in das RAW Format ausreichend sein. Dazu
einfach die Checkbox "RAM Data" anhacken und es wird eine C Header Datei
gespeichert in der die Pixel mit 16Bit Farbwerten codiert sind.
Für die anderen 3 Datenformate die ich verwende kann ich noch
Erklärungen und Beispielcode in C nachliefern, wenn gewünscht. Vorerst
nur mal par Stichpunkte was drinnen ist:
- 1 Farb Bitmaps, das sind nichts anderes als mit einer Farbe
ausgefüllte Rechtecke, quasi leere Bitmaps mit einer Hintergrundfarbe
- 16 Bit Bitmaps, das sind unkomprimierte Bitmaps in voller Farbe,
meistens weil eine Komprimierung nichts bringt
- Monochrome Bitmaps (2 Farben) mit Komprimierung. Die Daten sind per
RLE komprimiert und man erreicht ca. 2000-3000% Packungsrate im
Vergleich zu RAW
- 2 Bit bis 15 Bit Farbbitmaps, also von 3 Farben bis 32765 Farben. Die
Daten sind komprimiert und benutzen eine Farbtabelle. Die
Komprimierungsrate ist fast immer besser als bei PNG Bildern. Wichtig
ist das man nur durchschnittlich 16 AVR Takte pro Datenbyte in den
Zeichenroutinen benötigt für diese Dekomprimierung. Man erreicht also
defakto den maximalen Datendurchsatz bei 8Mhz SPI auf einem 16Mhz AVR ,
direkt aus dem FLASH ohne zusätzlichen SRAM zu verbrauchen.
Die Software selber kann
- PNG, BMP, WMF, EMF, ICO, JPEG laden
- in beliebigem Farbformat
- in beliebiger Größe
- das Bild wird runter skaliert auf maximal 176x132 Pixeln wenn nötig,
Seitenverhältnis wird beibehalten
- die Farbpalette/-anzahl kann reduziert werden
- das Bild kann in 90 Gradschritte rotiert, und gespiegelt werden
Gruß Hagen
Ausschnitt meines bisherigen Codes für meine S65-GLCD des LPH88xxx
Display (Philips HD66773R Controller).
1 #include "glcd.h"
2
3 uint16_t colormasks [ 14 ] PROGMEM = { 0x0006 , 0x000E , 0x001E , 0x003E , 0x007E , 0x00FE , 0x01FE , 0x03FE , 0x07FE , 0x0FFE , 0x1FFE , 0x3FFE , 0x7FFE , 0xFFFE };
4
5 void glcdDrawBitmap ( glcdCoord_t x , glcdCoord_t y , const prog_char * bitmap , uint8_t flags ) {
6
7
8 #define GLCD_LOAD_BITS(data0, data2, databits, addr, bitsmul) \
9 asm volatile( \
10 "cpi %2, lo8(16)" "\n\t" \
11 "brsh .%=2" "\n\t" \
12 "movw r30, %A3" "\n\t" \
13 "lpm r0, Z+" "\n\t" \
14 "mul r0, %4" "\n\t" \
15 "cpi %2, lo8(8)" "\n\t" \
16 "brsh .%=1" "\n\t" \
17 "or %A0, r0" "\n\t" \
18 "or %B0, r1" "\n\t" \
19 "subi %2, lo8(-(8))" "\n\t" \
20 "lpm r0, Z+" "\n\t" \
21 "mul r0, %4" "\n\t" \
22 ".%=1:" "\n\t" \
23 "or %B0, r0" "\n\t" \
24 "or %1, r1" "\n\t" \
25 "subi %2, lo8(-(8))" "\n\t" \
26 "movw %A3, r30" "\n\t" \
27 ".%=2:" "\n\t" \
28 "clr r1" "\n\t" \
29 : "=r" (data0), \
30 "=r" (data2), \
31 "=a" (databits), \
32 "=r" (addr), \
33 "=r" (bitsmul) \
34 : "r" (data0), \
35 "r" (data2), \
36 "a" (databits), \
37 "r" (addr), \
38 "r" (bitsmul) \
39 : "r0", "r1", "r30", "r31" \
40 );
41
42 #define GLCD_LOAD_COLOR(data0, data2, databits, colortable, colormask, bpp, bitsmul, bkcolor) \
43 asm volatile( \
44 "movw r30, %A0" "\n\t" \
45 "lsr %1" "\n\t" \
46 "ror %B0" "\n\t" \
47 "ror %A0" "\n\t" \
48 "brcs .%=0" "\n\t" \
49 "dec %2" "\n\t" \
50 "lsr %6" "\n\t" \
51 "brne .%=3" "\n\t" \
52 "ori %6, lo8(0x80)" "\n\t" \
53 "rjmp .%=3" "\n\t" \
54 ".%=0:" "\n\t" \
55 "and r30, %A4" "\n\t" \
56 "and r31, %B4" "\n\t" \
57 "add r30, %A3" "\n\t" \
58 "adc r31, %B3" "\n\t" \
59 "lpm %A7, Z+" "\n\t" \
60 "lpm %B7, Z" "\n\t" \
61 "mov r30, %5" "\n\t" \
62 "cpi r30, lo8(8)" "\n\t" \
63 "brlo .%=1" "\n\t" \
64 "mov %A0, %B0" "\n\t" \
65 "mov %B0, %1" "\n\t" \
66 "clr %1" "\n\t" \
67 "andi r30, lo8(0x07)" "\n\t" \
68 "breq .%=2" "\n\t" \
69 ".%=1:" "\n\t" \
70 "lsr %1" "\n\t" \
71 "ror %B0" "\n\t" \
72 "ror %A0" "\n\t" \
73 "dec r30" "\n\t" \
74 "brne .%=1" "\n\t" \
75 ".%=2:" "\n\t" \
76 "sub %2, %5" "\n\t" \
77 "dec %2" "\n\t" \
78 "mov r30, %2" "\n\t" \
79 "andi r30, lo8(0x07)" "\n\t" \
80 "clr r31" "\n\t" \
81 "subi r30, lo8(-(powerof2))" "\n\t" \
82 "sbci r31, hi8(-(powerof2))" "\n\t" \
83 "lpm %6, Z" "\n\t" \
84 ".%=3:" "\n\t" \
85 : "=r" (data0), \
86 "=r" (data2), \
87 "=a" (databits), \
88 "=r" (colortable), \
89 "=r" (colormask), \
90 "=r" (bpp), \
91 "=r" (bitsmul), \
92 "=r" (bkcolor) \
93 : "r" (data0), \
94 "r" (data2), \
95 "a" (databits), \
96 "r" (colortable), \
97 "r" (colormask), \
98 "r" (bpp), \
99 "r" (bitsmul), \
100 "r" (bkcolor) \
101 : "r30", "r31" \
102 );
103
104
105 if ( ! ( bitmap )) return ;
106 uint8_t w = pgm_read_byte_inc ( bitmap );
107 if ( ! ( w )) return ;
108 uint8_t h = pgm_read_byte_inc ( bitmap );
109 if ( ! ( h )) return ;
110 uint8_t bpp = pgm_read_byte_inc ( bitmap );
111 uint16_t bkcolor = pgm_read_word_inc ( bitmap );
112 if ( flags & GLCD_BMP_USECOLORS ) bkcolor = glcd . Colors [ 0 ];
113 if ( bpp == 0 ) {
114 glcdFillRect ( x , y , x + w - 1 , y + h - 1 , bkcolor );
115 return ;
116 }
117 GLCD_CS_ON ();
118 GLCD_SETADDR ( x , y );
119 GLCD_WINDOW ( x , y , x + w - 1 , y + h - 1 );
120 if ( flags & GLCD_BMP_TRANSPARENT ) {
121 GLCD_SETMODE ( 0x38 | GLCD_ROP_WNE );
122 GLCD_SETCOMPARE ( bkcolor );
123 } else {
124 GLCD_SETMODE ( 0x38 );
125 }
126 GLCD_STARTDATA ();
127 if ( bpp == 1 ) { // monochrome
128 uint16_t pixelcount = w * h ;
129 uint16_t fgcolor = pgm_read_word_inc ( bitmap );
130 if ( flags & GLCD_BMP_USECOLORS ) fgcolor = glcd . Colors [ 1 ];
131 uint16_t color = bkcolor ;
132 if ( flags & GLCD_BMP_SWAPCOLORS ) {
133 bkcolor = fgcolor ;
134 fgcolor = color ;
135 color = bkcolor ;
136 }
137 uint8_t data = pgm_read_byte_inc ( bitmap );
138 uint8_t pixelbits = (( data >> 4 ) + 1 ) << 2 ;
139 data &= 0x0F ;
140 uint8_t temp = data << 4 ;
141 data |= temp ;
142 do {
143 GLCD_WAIT ();
144 GLCD_OUT ( H8 ( color ));
145 if ( ! ( -- pixelbits )) {
146 data = pgm_read_byte_inc ( bitmap );
147 pixelbits = (( data >> 4 ) + 1 ) << 2 ;
148 data &= 0x0F ;
149 uint8_t temp = data << 4 ;
150 data |= temp ;
151 }
152 GLCD_WAIT ();
153 GLCD_OUT ( L8 ( color ));
154 ROL ( data ); // rotate data, data = (data << 1) | (data >> 7);
155 color = bkcolor ;
156 if ( data & 0x01 ) color = fgcolor ;
157 } while ( -- pixelcount );
158 } else if ( bpp == 16 ) { // full color
159 uint16_t pixelcount = w * h ;
160 while ( pixelcount ) {
161 GLCD_WAIT ();
162 GLCD_OUT ( H8 ( bkcolor ));
163 pixelcount -- ;
164 GLCD_WAIT ();
165 GLCD_OUT ( L8 ( bkcolor ));
166 bkcolor = pgm_read_word_inc ( bitmap );
167 }
168 } else { // color, 2 upto 15 BPP
169 uint16_t colortablesize = pgm_read_word_inc ( bitmap );
170 uint8_t * colortable = ( uint8_t * ) bitmap ;
171 bitmap += colortablesize ;
172 uint16_t colormask = pgm_read_word ( & colormasks [ bpp - 2 ]);
173 uint8_t databits = 0 , data2 = 0 , bitsmul = 1 ;
174 uint16_t data0 = 0 ;
175 // uint32_t data = 0;
176 uint16_t pixelcount = w * h ;
177 do {
178 GLCD_WAIT ();
179 GLCD_OUT ( H8 ( bkcolor ));
180 pixelcount -- ;
181 GLCD_LOAD_BITS ( data0 , data2 , databits , bitmap , bitsmul );
182
183 // while (databits < 16) {
184 // uint16_t t = pgm_read_byte_inc(bitmap) * bitsmul;
185 // if (databits >= 8) data |= (uint32_t)t << 8;
186 // else data |= t;
187 // databits += 8;
188 // }
189
190 GLCD_WAIT ();
191 GLCD_OUT ( L8 ( bkcolor ));
192
193 GLCD_LOAD_COLOR ( data0 , data2 , databits , colortable , colormask , bpp , bitsmul , bkcolor );
194
195 // if (LL8(data) & 0x01) {
196 // bkcolor = pgm_read_word(colortable + (L16(data) & colormask));
197 // data >>= bpp;
198 // databits -= bpp;
199 // bitsmul = pgm_read_byte(&powerof2[databits & 0x07]);
200 // }
201 // bitsmul >>= 1;
202 // if (!(bitsmul)) bitsmul |= 0x80;
203 // data >>= 1;
204 // databits--;
205 } while ( pixelcount );
206 }
207 GLCD_WAIT ();
208 GLCD_CS_PULSE ();
209 GLCD_SETMODE ( 0x30 );
210 GLCD_CS_OFF ();
211 }
von
Michele B.
(luxx )
19.12.2006 14:35
super sache! vielen dank!
Sorry, dieser Beitrag sollte hier eigentlich garnicht landen. Könnte
aber auch seine Vorteile haben einen extra Thread abzuspalten.
Es geht um eine PC Software die Bilder auf dem PC so bearbeitet und
konvertiert das man sie auf den S65 Displays benutzen kann.
Gruß Hagen
von
Franz (Gast)
11.09.2008 22:38
Hallo,
super Programm - kann ich das auch für andere Bildgrößen kriegen?
von
Richard (Gast)
27.07.2009 16:06
Hi,
versuche gerade ein kleines Bitmap (10x10 Pixel) auf meinem S65 LCD
darzustellen. Habe den Converter von Hagen Re benutzt um die Bilddaten
als raw data in einem array zu speichern. Das Bild im Anhang möchte ich
gerne darstellen lassen. Zu sehen ist aber nur ein bunter Pixelhaufen.
So sehen die raw daten des Bildes aus:
1 uint8_t img_bmp [] PROGMEM =
2 { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
3 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
4 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
5 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
6 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
7 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
8 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
9 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
10 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 ,
11 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 ,
12 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 ,
13 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 , 0xF8 , 0x00 ,
14 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
15 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
16 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
17 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
18 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
19 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
20 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xF8 , 0x00 ,
21 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };
Und das sind die Routinen für die Bildwiedergabe von Christian Kranz:
1 void LCD_WrData ( unsigned char data )
2 {
3 CLR ( LCD_CS );
4 CLR ( LCD_RS );
5 SPDR = data ;
6 while ( ! ( SPSR & ( 1 << SPIF )));
7 SET ( LCD_CS );
8 }
9
10 void S65_wrcmd16 ( uint16_t dat )
11 {
12 LCD_WrCmd (( dat >> 8 ));
13 LCD_WrCmd ( dat );
14 }
15
16 void S65_allocatearea ( uint8_t x1 , uint8_t y1 , uint8_t x2 , uint8_t y2 )
17 {
18 uint8_t x , y ;
19 if ( x1 < x2 )
20 {
21 x = x2 ;
22 x2 = x1 ;
23 x1 = x ;
24 }
25 if ( y2 < y1 )
26 {
27 y = y1 ;
28 y1 = y2 ;
29 y2 = y ;
30 }
31 S65_wrcmd16 ( 0xEF80 );
32 S65_wrcmd16 ( 0x1805 );
33 S65_wrcmd16 ( 0x1200 + x1 );
34 S65_wrcmd16 ( 0x1500 + x2 );
35 S65_wrcmd16 ( 0x1300 + y1 );
36 S65_wrcmd16 ( 0x1600 + y2 );
37 }
38
39 void S65_PutRawBmp16 ( uint8_t x , uint8_t y , uint8_t * pic , uint8_t w , uint8_t h )
40 {
41 uint8_t dimx = w - 1 ;
42 uint8_t dimy = h - 1 ;
43 S65_allocatearea ( x , y , x + dimx , y + dimy );
44
45 for ( uint16_t counter = 0 ; counter < (( dimx + 1 ) * ( dimy + 1 )) * 2 ; counter ++ )
46 {
47 LCD_WrData ( pgm_read_byte_near ( & pic [ counter ]));
48 }
49 }
Wird dann in der main() so aufgerufen:
1 S65_PutRawBmp16 ( 60 , 60 , img_bmp , 10 , 10 );
Ich betreibe das Display an einem ATmega644 bei 16MHz. Die Wiedergabe
von Text funktioniert bereits. Nur mit dem Bild habe ich Probleme.
Wer hat einen Tipp für mich?
Gruß
Richard
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.