This library is designed to make it easy for anyone to get the Nokia 5110 84x48 display 3.3V module up and running without delay It provides a convenient interface for printing single characters or strings of characters and vertical bar graphs, all at various magnifications. It is free to use and modify. I accept NO liability for malfunctions or damage caused by this software I hope it is useful to the community and am open to suggestions for improvement.
N_5110_Display.cpp
00001 #include "mbed.h" 00002 #include "N_5110_Display.h" 00003 #include "N_5110_Font.h" 00004 00005 00006 N_5110_Display::N_5110_Display( PinName _mosi, PinName _miso, PinName _sclk, PinName _dc, PinName _reset, PinName _cs): 00007 spi( _mosi, _miso, _sclk ), dc( _dc ), rst( _reset ), cs( _cs ) 00008 { 00009 initDisplay(); 00010 } 00011 00012 //---------------------------------------------------------------------- 00013 00014 void N_5110_Display::initDisplay() 00015 { 00016 rst=0; //display reset 00017 cs=1; //Chip Disabled 00018 00019 wait(0.5); //allow chip to settle for half second 00020 00021 spi.format(8,3); //set the SPI interface perameters for the Display 00022 spi.frequency(1000000); //1 MHz clock speed 00023 PixX = 0; //zero the x, y variables 00024 CharX = 0; 00025 CharY = 0; 00026 00027 rst=1; //display reset done 00028 00029 dc=0; //select Control mode 00030 cs=0; //Chip Enabled 00031 00032 spi.write(0x21); //Function Set (Extenden Instructions) 00033 spi.write(0x04); //set 'Temp Coef' value 00034 spi.write(0x13); //set 'Bias' value 00035 spi.write(0xBF); //set 'V_op' value 00036 spi.write(0x22); //Function Set (Basic Instructions) 00037 spi.write(0x0C); //Display Control 00038 00039 clrDisp(); //Clear the Display 00040 } 00041 00042 //---------------------------------------------------------------------- 00043 00044 void N_5110_Display::clrDisp() 00045 { 00046 long x; 00047 00048 dc=1; //select Data mode 00049 cs=0; //Chip Enabled 00050 00051 for (x=0; x<504; x++) //Clear the display memory 00052 { 00053 spi.write( 0 ); 00054 } 00055 00056 cs=1; //Chip Disabled 00057 } 00058 00059 //---------------------------------------------------------------------- 00060 00061 void N_5110_Display::setDispPos(int DispX, int DispY) 00062 { 00063 unsigned char Xtemp, Ytemp; 00064 00065 Xtemp = DispX | 0x80; //add in the column select BIT 00066 Ytemp = (DispY & 0x07) | 0x40; 00067 00068 dc=0; //select Control mode 00069 cs=0; //Chip Enabled 00070 00071 spi.write(Xtemp); //Set the column value 00072 spi.write(Ytemp); //set the row value 00073 00074 cs=1; //Chip Disabled 00075 } 00076 00077 //---------------------------------------------------------------------- 00078 00079 int N_5110_Display::setCharPos(int x, int y) 00080 //x is the character column number 0 to 13. y is the character row number 0 to 5. 00081 //The column is multiplied by 6 to get the display column value, as each 5 x 8 char occupies a 6 x 8 space 00082 { 00083 unsigned char Xacc; 00084 00085 if (x>13 || y>5) return -1; //check magnitude of co-ordinates and store 00086 00087 Xacc = x<<2; //multiply the char column (x) by 6 to get the Display column 00088 Xacc = Xacc + (x<<1); 00089 00090 PixX = Xacc; 00091 CharX = x; 00092 CharY = y; 00093 00094 setDispPos(PixX, CharY); 00095 00096 return 0; 00097 } 00098 00099 //---------------------------------------------------------------------- 00100 00101 void N_5110_Display::clrMagArray( unsigned char Xmag, unsigned char Ymag, bool FullWidth ) 00102 { 00103 unsigned char magDataX, magDataY, width; 00104 00105 width = FullWidth?6:5; 00106 00107 for (magDataX=0; magDataX<Xmag*width; magDataX++) //clear the magnification array 00108 { 00109 for (magDataY=0; magDataY<Ymag; magDataY++) 00110 { 00111 magData[magDataX][magDataY] = 0; 00112 } 00113 } 00114 } 00115 00116 //---------------------------------------------------------------------- 00117 00118 void N_5110_Display::smoothEdges( unsigned char Xmag, unsigned char Ymag ) 00119 //Quick and dirty character smoothing but only if there is magnification in both X and Y directions. Intended to improve readability 00120 //at higher magnifications but doesn't realy smooth very well. 00121 //I'm sure that someone can come up with a better solution than this, but I didn't have time to code an Interpolation algorithm or 00122 //creata vectored drawing system. 00123 { 00124 unsigned char Xpos, Ypos, tempByte1, tempByte2, tempByte3, and1, and2, totaland, repeater; 00125 00126 if (Xmag<2 || Ymag<2) return; //check for enough magnification to work with 00127 00128 for (repeater=0; repeater<(Xmag*Ymag)/(Xmag+Ymag); repeater++) //calc sensible number of itterations 00129 { 00130 00131 for (Ypos=0; Ypos<Ymag; Ypos++) 00132 { 00133 for (Xpos=0; Xpos<Xmag*6-1; Xpos++) //scan left to right 00134 { 00135 tempByte1 = magData[Xpos+1][Ypos]; //get the following byte 00136 tempByte2 = magData[Xpos][Ypos]; //get the current byte 00137 tempByte3 = tempByte1 ^ tempByte2; //check for a change 00138 00139 if (tempByte3 != 0) 00140 { 00141 tempByte2 >>= 1; //shift up (Right towards LSB) 00142 00143 if (Ypos+1 <= Ymag) 00144 { 00145 tempByte3 = magData[Xpos][Ypos+1]; //get missing BIT from byte below 00146 tempByte3 <<= 7; 00147 tempByte2 |= tempByte3; 00148 } 00149 00150 and1 = tempByte1 & tempByte2; 00151 00152 tempByte2 = magData[Xpos][Ypos]; //re-load the current byte 00153 tempByte2 <<= 1; //shift down (Left towards the MSB) 00154 00155 if (Ypos > 0) 00156 { 00157 tempByte3 = magData[Xpos][Ypos-1]; //get missing BIT from byte above 00158 tempByte3 >>= 7; 00159 tempByte2 |= tempByte3; 00160 } 00161 00162 and2 = tempByte1 & tempByte2; 00163 00164 totaland = (and1 | and2); 00165 magData[Xpos][Ypos] |= totaland; //incorpoate the extra bits into the magData } 00166 } 00167 } 00168 00169 for (Xpos=Xmag*6; Xpos>0; Xpos--) //scan right to left 00170 { 00171 tempByte1 = magData[Xpos-2][Ypos]; //get following byte 00172 tempByte2 = magData[Xpos-1][Ypos]; //get the current byte 00173 tempByte3 = tempByte1 ^ tempByte2; //check for change 00174 00175 if (tempByte3 != 0) 00176 { 00177 tempByte2 >>= 1; //shift up (Right towards the LSB) 00178 00179 if (Ypos+1 <= Ymag) 00180 { 00181 tempByte3 = magData[Xpos-1][Ypos+1]; //get missing BIT from byte below 00182 tempByte3 <<= 7; 00183 tempByte2 |= tempByte3; 00184 } 00185 00186 and1 = tempByte1 & tempByte2; 00187 00188 tempByte2 = magData[Xpos-1][Ypos]; //re-load the current byte 00189 tempByte2 <<= 1; //shift down (Left towards the MSB) 00190 00191 if (Ypos > 0) 00192 { 00193 tempByte3 = magData[Xpos-1][Ypos-1]; //get missing Bits from byte above 00194 tempByte3 >>= 7; 00195 tempByte2 |= tempByte3; 00196 } 00197 and2 = tempByte1 & tempByte2; 00198 00199 totaland = (and1 | and2); 00200 magData[Xpos - 1][Ypos] |= totaland; 00201 } 00202 } 00203 } 00204 } 00205 } 00206 00207 //---------------------------------------------------------------------- 00208 00209 void N_5110_Display::magChar( unsigned char c, unsigned char Xmag, unsigned char Ymag ) 00210 //Expand the basic 5 x 8 char def to the required X and y magnification using an buffer Array 00211 { 00212 unsigned char tempPat, count, Idx, Xexp, Yexp, bitCounter, bitAcc, srcBit, magDataX, magDataY; 00213 00214 clrMagArray( Xmag, Ymag, false ); 00215 00216 Idx = c - 32; //shift the ASCII code so it starts from zero 00217 00218 magDataX = 0; 00219 00220 for (count=0; count<5; count++) //5 bytes per char def 00221 { 00222 bitCounter = Ymag/2; //offset the image Y position by half the Y magnification factor 00223 bitAcc = 0; 00224 magDataY = 0; 00225 tempPat = font_data[Idx][count]; //get column Bit pattern to expand in the y direction by bit replication 00226 //LSB is top Bit position 00227 00228 for (srcBit=0; srcBit<8; srcBit++) //process each of the 8 bits in the source byte 00229 { 00230 for (Yexp=0; Yexp<Ymag; Yexp++) //each Bit in each def byte is duplicated Ymag times in the Y direction 00231 { 00232 bitAcc >>= 1; //shift the accumulator 1 bit to the left 00233 00234 if ((tempPat & 1) > 0) 00235 { 00236 bitAcc |= 0x80; //set msb 00237 } else { 00238 bitAcc &= 0x7F; //clear msb 00239 } 00240 00241 bitCounter++; 00242 00243 if (bitCounter > 7) //if the bit accumulator is full then store it and clear it to continue 00244 { 00245 for (Xexp=0; Xexp<Xmag; Xexp++) //do the X magnification while storingthe Bit Accumulator 00246 { 00247 magData[magDataX + Xexp][magDataY] = bitAcc; 00248 } 00249 00250 bitAcc = 0; 00251 magDataY++; 00252 bitCounter = 0; 00253 } 00254 } 00255 tempPat>>=1; 00256 } 00257 magDataX += Xmag; 00258 } 00259 smoothEdges( Xmag, Ymag ); 00260 } 00261 00262 //---------------------------------------------------------------------- 00263 00264 int N_5110_Display::outputMagData (unsigned char Xmag, unsigned char Ymag, bool FullWidth ) 00265 { 00266 unsigned char XpixTemp, mx, my, width; 00267 00268 XpixTemp = PixX; 00269 width = FullWidth?6:5; 00270 00271 if (FullWidth == false) 00272 { 00273 for (mx=0; mx<Xmag/2; mx++) 00274 { 00275 dc=1; //select Data mode 00276 cs=0; //Chip Enabled 00277 00278 for (my=0; my<Ymag; my++) 00279 { 00280 spi.write( 0 ); 00281 } 00282 00283 cs=1; //Chip Disabled 00284 00285 XpixTemp += 1; 00286 setDispPos(XpixTemp, CharY); 00287 } 00288 } 00289 00290 for (mx=0; mx<Xmag*width; mx++) 00291 { 00292 dc=1; //select Data mode 00293 cs=0; //Chip Enabled 00294 00295 for (my=0; my<Ymag; my++) 00296 { 00297 spi.write( magData[mx][my] ); 00298 } 00299 00300 cs=1; //Chip Disabled 00301 00302 XpixTemp += 1; 00303 setDispPos( XpixTemp, CharY ); 00304 } 00305 00306 if (FullWidth == false) 00307 { 00308 for (mx=0; mx<(Xmag+1)/2; mx++) 00309 { 00310 dc=1; //select Data mode 00311 cs=0; //Chip Enabled 00312 00313 for (my=0; my<Ymag; my++) 00314 { 00315 spi.write( 0 ); 00316 } 00317 00318 cs=1; //Chip Disabled 00319 00320 XpixTemp += 1; 00321 setDispPos(XpixTemp, CharY); 00322 } 00323 } 00324 00325 PixX = XpixTemp; 00326 CharX += Xmag; 00327 00328 return 0; 00329 } 00330 00331 //---------------------------------------------------------------------- 00332 00333 int N_5110_Display::print1char(unsigned char c, unsigned char Xmag, unsigned char Ymag) 00334 { 00335 if (c<32 | c>127) return -1; //Exit if char is out of range 00336 00337 if (Xmag<1) Xmag=1; //Clamp the magnification values 00338 if (Ymag<1) Ymag=1; 00339 if (Xmag>6) Xmag=6; 00340 if (Ymag>6) Ymag=6; 00341 00342 magChar( c, Xmag, Ymag ); 00343 00344 outputMagData( Xmag, Ymag, false ); 00345 00346 return 0; 00347 } 00348 00349 //---------------------------------------------------------------------- 00350 00351 void N_5110_Display::printString( char * str2prt, unsigned char Xmag, unsigned char Ymag) 00352 { 00353 unsigned char c; 00354 00355 for (c=0; c<strlen(str2prt); c++) 00356 { 00357 print1char( str2prt[c], Xmag, Ymag ); 00358 } 00359 } 00360 00361 //---------------------------------------------------------------------- 00362 00363 void N_5110_Display::VertBarGraph( int Percentage, unsigned char Xmag, unsigned char Ymag ) 00364 { 00365 unsigned char Xidx, Yidx, activeHeight, wholeBytes, pixRemaining, mask, count, dither; 00366 00367 if (Xmag<1) Xmag=1; //Clamp the magnification values 00368 if (Ymag<1) Ymag=1; 00369 if (Xmag>6) Xmag=6; 00370 if (Ymag>6) Ymag=6; 00371 00372 clrMagArray( Xmag, Ymag, true ); 00373 00374 activeHeight = 8 * Ymag * Percentage /100; //Calc the magnitude of the Bar 00375 wholeBytes = activeHeight / 8; 00376 pixRemaining = activeHeight % 8; 00377 00378 mask = 0xFF; 00379 for(count=0; count<8-pixRemaining; count++) //creat the mask for pixRemaining 00380 { 00381 mask <<= 1; 00382 } 00383 00384 for (Xidx=0; Xidx<6*Xmag-1; Xidx++) //step along the pixel columns 00385 { 00386 dither = Xidx&1?0x55:0xAA; //Dither value alternates for each odd, ecen pixel column 00387 00388 for (Yidx=0; Yidx<Ymag; Yidx++) //step through each row 00389 { 00390 if (Yidx == Ymag - wholeBytes - 1) //do the remainder 00391 { 00392 magData[Xidx][Yidx] |= dither; 00393 magData[Xidx][Yidx] &= mask; 00394 } 00395 else if (Yidx >= Ymag-wholeBytes) //else do the whole bytes 00396 { 00397 magData[Xidx][Yidx] |= dither; 00398 } 00399 //now add the border 00400 if (Xidx==0 || Xidx==6*Xmag-2) //Left & Right 00401 { 00402 magData[Xidx][Yidx] |= 0xFF; 00403 } 00404 00405 if (Yidx==0) //Top 00406 { 00407 magData[Xidx][Yidx] |= 0x01; 00408 } 00409 00410 if (Yidx==Ymag-1) //Bottom 00411 { 00412 magData[Xidx][Yidx] |= 0x40; 00413 magData[Xidx][Yidx] &= 0x7F; 00414 } 00415 } 00416 } 00417 00418 outputMagData( Xmag, Ymag, true ); 00419 } 00420
Generated on Thu Jul 21 2022 18:04:56 by
1.7.2
Pete Isley