Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
glcd.cpp
00001 /*********************************************************** 00002 Author: Dupuy Bruno 00003 Date: 5 mars 2001 00004 Version: beta 00005 ************************************************************/ 00006 #include "glcd.h" 00007 00008 GLCD::GLCD (PinName _DI, PinName _RW, PinName _E, PinName _CS2, PinName _CS1, BusInOut *BUSLCD):GLCD_DI(_DI),GLCD_RW(_RW),GLCD_E(_E),GLCD_CS2(_CS2),GLCD_CS1(_CS1) { 00009 LCD_PORT = BUSLCD; 00010 ready = false; 00011 } 00012 00013 void GLCD::reset_pins(int val) { 00014 GLCD_DI = val; 00015 GLCD_RW = val; 00016 GLCD_E = val; 00017 GLCD_CS2 = val; 00018 GLCD_CS1 = val; 00019 LCD_PORT->output(); 00020 LCD_PORT->write((val==0)?(0):(0xFF)); 00021 } 00022 00023 void GLCD::setTest(int step) { 00024 char* strpin[] = {"DI", "RW", "E" ,"CS2", "CS1"}; 00025 DigitalOut* ctrl[] = {&GLCD_DI, &GLCD_RW , &GLCD_E, &GLCD_CS2, &GLCD_CS1}; 00026 printf("\n\rScanning all lcd pins mode:%d\n\r",step); 00027 if (step== 0) { 00028 reset_pins(0);; 00029 printf("All pins are set to 0\n\r"); 00030 } 00031 if (step > 0 && step < 6) { 00032 ctrl[step-1]->write(1); 00033 printf("Pins (%s) is set to 1\n\r", strpin[step-1]); 00034 } 00035 if (step > 5 & step < 14) { 00036 LCD_PORT->write((1<<(step-6))); 00037 printf("Pins LCD_PORT are set to value 0x%X\n\r", (1<<(step-6))); 00038 } 00039 if (step == 255) { 00040 reset_pins(1);; 00041 printf("All pins are set to 1\n\r"); 00042 } 00043 } 00044 00045 bool GLCD::isUsed() { 00046 return isused; 00047 } 00048 00049 bool GLCD::getXor() { 00050 return _xor; 00051 } 00052 void GLCD::setXor(bool s) { 00053 _xor = s; 00054 } 00055 00056 // Purpose: Write a byte of data to the specified chip 00057 // Inputs: 1) chipSelect - which chip to write the data to 00058 // 2) data - the byte of data to write 00059 void GLCD::writeByte(unsigned char side, unsigned char data) { 00060 // Choose which side to write to 00061 if (side == LEFT) GLCD_CS2 = 1; 00062 else GLCD_CS1 = 1; 00063 GLCD_RW = 0; // Set for writing 00064 LCD_PORT->write(data); // Put the data on the port 00065 GLCD_E = 1; // Pulse the enable pin 00066 wait_us(1); 00067 GLCD_E = 0; 00068 GLCD_CS1 = 0; // Reset the chip select lines 00069 GLCD_CS2 = 0; 00070 } 00071 00072 // Purpose: Reads a byte of data from the specified chip 00073 // Ouputs: A byte of data read from the chip 00074 unsigned char GLCD::readByte(unsigned char side) { 00075 unsigned char data; // Stores the data reading in LCD 00076 // Choose which side to write to 00077 if (side == LEFT) GLCD_CS2 = 1; 00078 else GLCD_CS1 = 1; 00079 LCD_PORT->input(); // Set port b to input 00080 GLCD_RW = 1; // Set for reading 00081 GLCD_E = 1; 00082 wait_us(1); 00083 GLCD_E = 0; // Pulse the enable pin 00084 // wait_us(1); 00085 GLCD_E = 1; 00086 wait_us(1); 00087 data = LCD_PORT->read(); // Get the data from the display's output register 00088 GLCD_E = 0; 00089 GLCD_CS1 = 0; // Reset the chip select lines 00090 GLCD_CS2 = 0; 00091 return data; // Return the read data 00092 } 00093 00094 void GLCD::init(bool mode) { 00095 ready = true; 00096 // Initialize some pins. 00097 // Don't reset because GLCD_RST is connected to VDD 00098 // GLCD_RST = 1; 00099 isused = true; 00100 _xor = false; 00101 GLCD_E = 0; 00102 GLCD_CS1 = 0; 00103 GLCD_CS2 = 0; 00104 GLCD_DI = 0; // Set for instruction 00105 LCD_PORT->output(); 00106 LCD_PORT->mode(PullDown); 00107 writeByte(LEFT, 0xC0); // Specify first RAM line at the top 00108 writeByte(RIGHT, 0xC0); // of the screen 00109 writeByte(LEFT, 0x40); // Set the column address to 0 00110 writeByte(RIGHT, 0x40); 00111 writeByte(LEFT, 0xB8); // Set the page address to 0 00112 writeByte(RIGHT, 0xB8); 00113 if (mode) { 00114 writeByte(LEFT, 0x3F); // Turn the display on 00115 writeByte(RIGHT, 0x3F); 00116 } else { 00117 writeByte(LEFT, 0x3E); // Turn the display off 00118 writeByte(RIGHT, 0x3E); 00119 } 00120 fillScreen(WHITE); // Clear the display 00121 repaint(); 00122 isused = false; 00123 } 00124 00125 // Purpose: Fill the LCD screen with the passed in color. 00126 // Works much faster than drawing a rectangle to fill the screen. 00127 // Inputs: ON - turn all the pixels on 00128 // OFF - turn all the pixels off 00129 void GLCD::fillScreen(bool color) { 00130 unsigned char data; 00131 char *p1, *p2; 00132 unsigned short i; 00133 p1 = left; 00134 p2 = right; 00135 data = 0xFF * color; 00136 for (i = 0; i < 512; ++i) { 00137 *p1++ = data; 00138 *p2++ = data; 00139 } 00140 } 00141 00142 // Exec time 5.221ms 00143 void GLCD::repaint() { 00144 int j, i; 00145 isused = true; 00146 char* p1 = left; 00147 char* p2 = right; 00148 int page = 0xB8; 00149 GLCD_DI = 0; // Set for instruction 00150 writeByte(LEFT, 0x40); // Set the column address to 0 00151 writeByte(RIGHT, 0x40); 00152 writeByte(LEFT, page); // Set the page address to 0 00153 writeByte(RIGHT, page); 00154 for (j = 0; j < 8; j++, page+=1) { 00155 GLCD_DI = 0; 00156 writeByte(LEFT, page); 00157 writeByte(RIGHT, page); 00158 for (i = 0; i < 64; i++) { 00159 GLCD_DI = 1; 00160 writeByte(LEFT, *p1++); 00161 writeByte(RIGHT, *p2++); 00162 } 00163 } 00164 isused = false; 00165 } 00166 00167 void GLCD::setPixel( unsigned short x, unsigned short y, bool color) { 00168 char* p; 00169 unsigned short temp; 00170 bool nec; 00171 if (x > 127 || y > 63) return; 00172 temp = y / 8; 00173 temp *= 64; 00174 temp += x; 00175 if (x > 63) 00176 p = right + temp - 64; 00177 else 00178 p = left + temp; 00179 if (_xor) 00180 nec = BIT_TEST(*p, y % 8) ^ color; 00181 else 00182 nec = color; 00183 if (nec == BLACK) 00184 BIT_SET(*p, y % 8); 00185 else 00186 BIT_CLEAR(*p, y % 8); 00187 } 00188 00189 bool GLCD::getPixel( unsigned short x, unsigned short y) { 00190 char* p; 00191 unsigned short temp; 00192 if (x > 127 || y > 63) return false; 00193 temp = y / 8; 00194 temp *= 64; 00195 temp += x; 00196 if (x > 63) 00197 p = right + temp - 64; 00198 else 00199 p = left + temp; 00200 return BIT_TEST(*p, y % 8); 00201 } 00202 00203 void GLCD::lineh( unsigned short x0, unsigned short y0, unsigned short x1, bool color) { 00204 unsigned short x; 00205 for (x = x0; x < x1; x++) { 00206 setPixel(x, y0, color); 00207 } 00208 } 00209 00210 void GLCD::linev( unsigned short x0, unsigned short y0, unsigned short y1, bool color) { 00211 unsigned short y; 00212 for (y = y0; y < y1; y++) { 00213 setPixel(x0, y, color); 00214 } 00215 } 00216 00217 // Purpose: Draw a line on a graphic LCD using Bresenham's 00218 // line drawing algorithm 00219 // Inputs: (x1, y1) - the start coordinate 00220 // (x2, y2) - the end coordinate 00221 // color - ON or OFF 00222 // Dependencies: pixel() 00223 void GLCD::line( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, char dash, bool color) { 00224 short x, y, addx, addy, dx, dy; 00225 signed long P; 00226 short i; 00227 int pat = 0; 00228 dx = abs((short)(x2 - x1)); 00229 dy = abs((short)(y2 - y1)); 00230 x = x1; 00231 y = y1; 00232 if (x1 > x2) 00233 addx = -1; 00234 else 00235 addx = 1; 00236 if (y1 > y2) 00237 addy = -1; 00238 else 00239 addy = 1; 00240 if (dx >= dy) { 00241 P = 2 * dy - dx; 00242 for (i = 0; i <= dx; ++i) { 00243 if ( (dash & (char)(1 << pat)) != 0) 00244 setPixel(x, y, color); 00245 pat = ( (pat<7)? (pat+1): ( 0 ) ); 00246 if (P < 0) { 00247 P += 2 * dy; 00248 x += addx; 00249 } else { 00250 P += 2 * dy - 2 * dx; 00251 x += addx; 00252 y += addy; 00253 } 00254 } 00255 } else { 00256 P = 2 * dx - dy; 00257 for (i = 0; i <= dy; ++i) { 00258 if ( (dash & (char)(1 << pat)) != 0) 00259 setPixel(x, y, color); 00260 pat = ( (pat<7)? (pat+1): ( 0 ) ); 00261 if (P < 0) { 00262 P += 2 * dx; 00263 y += addy; 00264 } else { 00265 P += 2 * dx - 2 * dy; 00266 x += addx; 00267 y += addy; 00268 } 00269 } 00270 } 00271 } 00272 00273 // Purpose: Draw a rectangle on a graphic LCD 00274 // Inputs: (x1, y1) - the start coordinate 00275 // (x2, y2) - the end coordinate 00276 // fill - YES or NO 00277 // color - ON or OFF 00278 // Dependencies: pixel(), line() 00279 void GLCD::rectangle( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, char dash, bool fill, bool color) { 00280 if (fill) { 00281 unsigned short y, ymax; // Find the y min and max 00282 if (y1 < y2) { 00283 y = y1; 00284 ymax = y2; 00285 } else { 00286 y = y2; 00287 ymax = y1; 00288 } 00289 for (; y <= ymax; ++y) 00290 // Draw lines to fill the rectangle 00291 line(x1, y, x2, y, dash, color); 00292 } else { 00293 line(x1, y1, x2, y1, dash, color); // Draw the 4 sides 00294 line(x1, y2, x2, y2, dash, color); 00295 line(x1, y1, x1, y2, dash, color); 00296 line(x2, y1, x2, y2, dash, color); 00297 } 00298 } 00299 00300 // Purpose: Draw a bar (wide line) on a graphic LCD 00301 // Inputs: (x1, y1) - the start coordinate 00302 // (x2, y2) - the end coordinate 00303 // width - The number of pixels wide 00304 // color - ON or OFF 00305 void GLCD::bar( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int width, bool color) { 00306 short x, y, addx, addy, j; 00307 int P, dx, dy, c1, c2; 00308 unsigned short i; 00309 dx = abs((short)(x2 - x1)); 00310 dy = abs((short)(y2 - y1)); 00311 x = x1; 00312 y = y1; 00313 c1 = -dx * x1 - dy * y1; 00314 c2 = -dx * x2 - dy * y2; 00315 if (x1 > x2) { 00316 addx = -1; 00317 c1 = -dx * x2 - dy * y2; 00318 c2 = -dx * x1 - dy * y1; 00319 } else 00320 addx = 1; 00321 if (y1 > y2) { 00322 addy = -1; 00323 c1 = -dx * x2 - dy * y2; 00324 c2 = -dx * x1 - dy * y1; 00325 } else 00326 addy = 1; 00327 if (dx >= dy) { 00328 P = 2 * dy - dx; 00329 for (i = 0; i <= dx; ++i) { 00330 for (j = -(width / 2); j < width 00331 / 2 + width % 2; ++j) { 00332 if (dx * x + dy * (y + j) + c1 >= 0 && dx * x + dy * (y + j) + c2 <= 0) 00333 setPixel(x, y + j, color); 00334 } 00335 if (P < 0) { 00336 P += 2 * dy; 00337 x += addx; 00338 } else { 00339 P += 2 * dy - 2 * dx; 00340 x += addx; 00341 y += addy; 00342 } 00343 } 00344 } else { 00345 P = 2 * dx - dy; 00346 for (i = 0; i <= dy; ++i) { 00347 if (P < 0) { 00348 P += 2 * dx; 00349 y += addy; 00350 } else { 00351 P += 2 * dx - 2 * dy; 00352 x += addx; 00353 y += addy; 00354 } 00355 for (j = -(width / 2); j < width/ 2 + width % 2; ++j) { 00356 if (dx * x + dy * (y + j) + c1 >= 0 && dx * x + dy * (y + j) + c2 <= 0) 00357 setPixel(x + j, y, color); 00358 } 00359 } 00360 } 00361 } 00362 00363 // Purpose: Draw a circle on a graphic LCD 00364 // Inputs: (x,y) - the center of the circle 00365 // radius - the radius of the circle 00366 // fill - YES or NO 00367 // color - ON or OFF 00368 void GLCD::circle( unsigned short x, unsigned short y, unsigned short radius, bool fill, bool color) { 00369 short a, b, P; 00370 a = 0; 00371 b = radius; 00372 P = 1 - radius; 00373 do { 00374 if (fill) { 00375 line(x - a, y + b, x + a, y + b, (char)0xff, color); 00376 line(x - a, y - b, x + a, y - b, (char)0xff, color); 00377 line(x - b, y + a, x + b, y + a, (char)0xff, color); 00378 line(x - b, y - a, x + b, y - a, (char)0xff, color); 00379 } else { 00380 setPixel(a + x, b + y, color); 00381 setPixel(b + x, a + y, color); 00382 setPixel(x - a, b + y, color); 00383 setPixel(x - b, a + y, color); 00384 setPixel(b + x, y - a, color); 00385 setPixel(a + x, y - b, color); 00386 setPixel(x - a, y - b, color); 00387 setPixel(x - b, y - a, color); 00388 } 00389 if (P < 0) 00390 P += 3 + 2 * a++; 00391 else 00392 P += 5 + 2 * (a++ - b--); 00393 } while (a <= b); 00394 } 00395 00396 /** 00397 * This functions draw an 00398 * ellipse. 00399 * 00400 * @param x {double} X coordinate 00401 * @param y {double} Y coordinate 00402 * @param a {double} Semimajor axis 00403 * @param b {double} Semiminor axis 00404 * @param angle {double} Angle of the ellipse 00405 */ 00406 unsigned short GLCD::ellipse(unsigned short x, unsigned short y,unsigned short a, unsigned short b, float angle, unsigned short steps, bool color) { 00407 if (steps == 0) 00408 steps = 36; 00409 00410 // Angle is given by Degree Value 00411 float beta = -angle * (PI / 180); //(Math.PI/180) converts Degree Value into Radians 00412 float sinbeta = sin(beta); 00413 float cosbeta = cos(beta); 00414 00415 for (int i = 0; i < 360; i += 360 / steps) { 00416 float alpha = i * (PI / 180) ; 00417 float sinalpha = sin(alpha); 00418 float cosalpha = cos(alpha); 00419 00420 float X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta); 00421 float Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta); 00422 setPixel((int)X, (int)Y, color); 00423 00424 } 00425 return x+a; 00426 } 00427 00428 unsigned short GLCD::icon(unsigned short xo, unsigned short yo, const char* iconptr, bool color, bool transparency) { 00429 unsigned short x, y, h, w, i=0; 00430 short b; 00431 char c; 00432 c = iconptr[i++]; // Codage 'H' or 'V' 00433 w = iconptr[i++]; // width in pixel 00434 h = iconptr[i++]; // height in pixel 00435 if (c=='V') { 00436 for (y=yo; y< yo + h; y+=8) { 00437 for (x = xo; x< xo + w; x++) { 00438 c = iconptr[i++]; 00439 for (b = 0; b < 8; b++) { 00440 if ( (y+b)-yo < h) { 00441 if (BIT_TEST(c, b)) 00442 setPixel(x, y+b, color); 00443 else if (!transparency) 00444 setPixel(x, y+b, !color); 00445 } 00446 } 00447 } 00448 } 00449 return xo + w; // last x position 00450 } 00451 if (c=='H') { 00452 for (y=yo; y< yo + h; y++) { 00453 for (x = xo; x< xo + w; x+=8) { 00454 c = iconptr[i++]; 00455 for (b = 0; b < 8; b++) { 00456 if ( (x+b)-xo < w) { 00457 if (BIT_TEST(c, b)) 00458 setPixel(x+b, y, color); 00459 else if (!transparency) 00460 setPixel(x+b, y, !color); 00461 } 00462 } 00463 } 00464 } 00465 return xo + w; // last x position 00466 } 00467 return xo + w; // last x position 00468 } 00469 00470 // Purpose: Write text on a graphic LCD 00471 // Inputs: (x,y) - The upper left coordinate of the first letter 00472 // textptr - A pointer to an array of text to display 00473 // fontptr - A pointer to font 00474 // size - The size of the text: 1 = 5x7, 2 = 10x14, ... 00475 // color - ON or OFF 00476 // transparency - ON or OFF 00477 unsigned short GLCD::text( unsigned short x, unsigned short y, const char* textptr, const char* fontptr, unsigned char size, bool color, bool transparency) { 00478 unsigned short i, j, k, l, m = 0; // Loop counters 00479 int w = fontptr[0]; // width 00480 int h = fontptr[1]; // height 00481 char fc = fontptr[2]; // First char 00482 char lc = fontptr[3]; // Last char 00483 char pixData; 00484 // Loop through the passed string 00485 for (i = 0; textptr[i] != '\0'; ++i, ++x) { 00486 // Loop through character byte data 00487 for (j = 0; j < w; ++j, x += size) { 00488 if ( textptr[i] >= fc && textptr[i] <= lc) 00489 pixData = fontptr[((textptr[i] - fc) * w + j) + 4]; 00490 else 00491 pixData = 0xAA; // Bad char 00492 // Loop through the vertical pixels 00493 for (k = 0; k < h; k++) { 00494 // Check if the pixel should be set 00495 if (BIT_TEST(pixData, k)) { 00496 // The next two loops change the character's size 00497 for (l = 0; l < size; ++l) { 00498 for (m = 0; m < size; ++m) { 00499 // Draws the pixel at color 00500 setPixel(x + m, y + k * size + l, color); 00501 } 00502 } 00503 } else { 00504 if (!transparency) { 00505 for (l = 0; l < size; ++l) { 00506 for (m = 0; m < size; ++m) { 00507 // Draws the pixel at ~color 00508 setPixel(x + m, y + k * size + l, !color); 00509 } 00510 } 00511 } 00512 } 00513 } 00514 } 00515 // Clean gap between two caracters 00516 if (!transparency) { 00517 for (k = 0; k < h * size; ++k) { 00518 // Draws the pixel at ~color 00519 setPixel(x, y + k, !color); 00520 } 00521 } 00522 } 00523 return x + m; // last x position 00524 }
Generated on Tue Jul 12 2022 19:44:09 by
1.7.2