Library for interfacing to Nokia 5110 LCD display (as found on the SparkFun website).

Dependents:   LV7_LCDtest LV7_Grupa5_Tim003_Zadatak1 lv7_Grupa5_Tim008_zad1 LV7_PAI_Grupa5_tim10_Zadatak1 ... more

This library is designed to make it easy to interface an mbed with a Nokia 5110 LCD display.

These can be found at Sparkfun (https://www.sparkfun.com/products/10168) and Adafruit (http://www.adafruit.com/product/338).

The library uses the SPI peripheral on the mbed which means it is much faster sending data to the display than other libraries available on other platforms that use software SPI.

The library can print strings as well as controlling individual pixels, meaning that both text and primitive graphics can be displayed.

Committer:
eencae
Date:
Tue Mar 10 19:21:47 2015 +0000
Revision:
14:520a02fc12aa
Parent:
12:022993561fd8
Child:
15:ee645611ff94
Expanded example and modified printChar().

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 5:6ea180eef702 1 /**
eencae 5:6ea180eef702 2 @file N5110.cpp
eencae 5:6ea180eef702 3
eencae 5:6ea180eef702 4 @brief Member functions implementations
eencae 5:6ea180eef702 5
eencae 5:6ea180eef702 6 */
eencae 0:d563e74f0ae9 7 #include "mbed.h"
eencae 0:d563e74f0ae9 8 #include "N5110.h"
eencae 0:d563e74f0ae9 9
eencae 2:e93021cfb0a9 10
eencae 1:df68f34cd32d 11 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
eencae 0:d563e74f0ae9 12 {
eencae 14:520a02fc12aa 13
eencae 0:d563e74f0ae9 14 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
eencae 14:520a02fc12aa 15 initSPI();
eencae 14:520a02fc12aa 16
eencae 6:adb79338d40f 17 // set up pins as required
eencae 0:d563e74f0ae9 18 led = new PwmOut(ledPin);
eencae 0:d563e74f0ae9 19 pwr = new DigitalOut(pwrPin);
eencae 0:d563e74f0ae9 20 sce = new DigitalOut(scePin);
eencae 0:d563e74f0ae9 21 rst = new DigitalOut(rstPin);
eencae 0:d563e74f0ae9 22 dc = new DigitalOut(dcPin);
eencae 0:d563e74f0ae9 23
eencae 0:d563e74f0ae9 24 }
eencae 0:d563e74f0ae9 25
eencae 6:adb79338d40f 26 // initialise function - powers up and sends the initialisation commands
eencae 0:d563e74f0ae9 27 void N5110::init()
eencae 0:d563e74f0ae9 28 {
eencae 6:adb79338d40f 29 turnOn(); // power up
eencae 6:adb79338d40f 30 wait_ms(10); // small delay seems to prevent spurious pixels during mbed reset
eencae 6:adb79338d40f 31 reset(); // reset LCD - must be done within 100 ms
eencae 0:d563e74f0ae9 32
eencae 0:d563e74f0ae9 33 // function set - extended
eencae 0:d563e74f0ae9 34 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 35 // Don't completely understand these parameters - they seem to work as they are
eencae 6:adb79338d40f 36 // Consult the datasheet if you need to change them
eencae 1:df68f34cd32d 37 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library
eencae 0:d563e74f0ae9 38 sendCommand(CMD_TC_TEMP_2); // temperature control
eencae 0:d563e74f0ae9 39 sendCommand(CMD_BI_MUX_48); // bias
eencae 0:d563e74f0ae9 40
eencae 0:d563e74f0ae9 41 // function set - basic
eencae 0:d563e74f0ae9 42 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 1:df68f34cd32d 43 normalMode(); // normal video mode by default
eencae 0:d563e74f0ae9 44 sendCommand(CMD_DC_NORMAL_MODE); // black on white
eencae 0:d563e74f0ae9 45
eencae 0:d563e74f0ae9 46 // RAM is undefined at power-up so clear
eencae 0:d563e74f0ae9 47 clearRAM();
eencae 0:d563e74f0ae9 48
eencae 0:d563e74f0ae9 49 }
eencae 14:520a02fc12aa 50
eencae 14:520a02fc12aa 51 // sets normal video mode (black on white)
eencae 14:520a02fc12aa 52 void N5110::normalMode()
eencae 14:520a02fc12aa 53 {
eencae 14:520a02fc12aa 54 sendCommand(CMD_DC_NORMAL_MODE);
eencae 14:520a02fc12aa 55
eencae 1:df68f34cd32d 56 }
eencae 1:df68f34cd32d 57
eencae 14:520a02fc12aa 58 // sets normal video mode (white on black)
eencae 14:520a02fc12aa 59 void N5110::inverseMode()
eencae 14:520a02fc12aa 60 {
eencae 14:520a02fc12aa 61 sendCommand(CMD_DC_INVERT_VIDEO);
eencae 1:df68f34cd32d 62 }
eencae 0:d563e74f0ae9 63
eencae 0:d563e74f0ae9 64 // function to power up the LCD and backlight
eencae 0:d563e74f0ae9 65 void N5110::turnOn()
eencae 0:d563e74f0ae9 66 {
eencae 0:d563e74f0ae9 67 // set brightness of LED - 0.0 to 1.0 - default is 50%
eencae 0:d563e74f0ae9 68 setBrightness(0.5);
eencae 0:d563e74f0ae9 69 pwr->write(1); // apply power
eencae 0:d563e74f0ae9 70 }
eencae 0:d563e74f0ae9 71
eencae 0:d563e74f0ae9 72 // function to power down LCD
eencae 0:d563e74f0ae9 73 void N5110::turnOff()
eencae 0:d563e74f0ae9 74 {
eencae 0:d563e74f0ae9 75 setBrightness(0.0); // turn backlight off
eencae 0:d563e74f0ae9 76 clearRAM(); // clear RAM to ensure specified current consumption
eencae 10:6f3abb40202b 77 // send command to ensure we are in basic mode
eencae 0:d563e74f0ae9 78 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 6:adb79338d40f 79 // clear the display
eencae 0:d563e74f0ae9 80 sendCommand(CMD_DC_CLEAR_DISPLAY);
eencae 6:adb79338d40f 81 // enter the extended mode and power down
eencae 0:d563e74f0ae9 82 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 83 // small delay and then turn off the power pin
eencae 6:adb79338d40f 84 wait_ms(10);
eencae 0:d563e74f0ae9 85 pwr->write(0);
eencae 0:d563e74f0ae9 86
eencae 0:d563e74f0ae9 87 }
eencae 0:d563e74f0ae9 88
eencae 0:d563e74f0ae9 89 // function to change LED backlight brightness
eencae 0:d563e74f0ae9 90 void N5110::setBrightness(float brightness)
eencae 0:d563e74f0ae9 91 {
eencae 0:d563e74f0ae9 92 // check whether brightness is within range
eencae 0:d563e74f0ae9 93 if (brightness < 0.0)
eencae 0:d563e74f0ae9 94 brightness = 0.0;
eencae 0:d563e74f0ae9 95 if (brightness > 1.0)
eencae 0:d563e74f0ae9 96 brightness = 1.0;
eencae 0:d563e74f0ae9 97 // set PWM duty cycle
eencae 0:d563e74f0ae9 98 led->write(brightness);
eencae 0:d563e74f0ae9 99 }
eencae 0:d563e74f0ae9 100
eencae 0:d563e74f0ae9 101
eencae 0:d563e74f0ae9 102 // pulse the active low reset line
eencae 0:d563e74f0ae9 103 void N5110::reset()
eencae 0:d563e74f0ae9 104 {
eencae 0:d563e74f0ae9 105 rst->write(0); // reset the LCD
eencae 0:d563e74f0ae9 106 rst->write(1);
eencae 0:d563e74f0ae9 107 }
eencae 0:d563e74f0ae9 108
eencae 0:d563e74f0ae9 109 // function to initialise SPI peripheral
eencae 0:d563e74f0ae9 110 void N5110::initSPI()
eencae 0:d563e74f0ae9 111 {
eencae 0:d563e74f0ae9 112 spi->format(8,1); // 8 bits, Mode 1 - polarity 0, phase 1 - base value of clock is 0, data captured on falling edge/propagated on rising edge
eencae 0:d563e74f0ae9 113 spi->frequency(4000000); // maximum of screen is 4 MHz
eencae 0:d563e74f0ae9 114 }
eencae 0:d563e74f0ae9 115
eencae 6:adb79338d40f 116 // send a command to the display
eencae 0:d563e74f0ae9 117 void N5110::sendCommand(unsigned char command)
eencae 0:d563e74f0ae9 118 {
eencae 0:d563e74f0ae9 119 dc->write(0); // set DC low for command
eencae 0:d563e74f0ae9 120 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 121 spi->write(command); // send command
eencae 0:d563e74f0ae9 122 dc->write(1); // turn back to data by default
eencae 0:d563e74f0ae9 123 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 124
eencae 0:d563e74f0ae9 125 }
eencae 0:d563e74f0ae9 126
eencae 6:adb79338d40f 127 // send data to the display at the current XY address
eencae 6:adb79338d40f 128 // dc is set to 1 (i.e. data) after sending a command and so should
eencae 6:adb79338d40f 129 // be the default mode.
eencae 0:d563e74f0ae9 130 void N5110::sendData(unsigned char data)
eencae 0:d563e74f0ae9 131 {
eencae 0:d563e74f0ae9 132 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 133 spi->write(data);
eencae 0:d563e74f0ae9 134 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 135 }
eencae 0:d563e74f0ae9 136
eencae 0:d563e74f0ae9 137 // this function writes 0 to the 504 bytes to clear the RAM
eencae 0:d563e74f0ae9 138 void N5110::clearRAM()
eencae 0:d563e74f0ae9 139 {
eencae 0:d563e74f0ae9 140 int i;
eencae 0:d563e74f0ae9 141 sce->write(0); //set CE low to begin frame
eencae 0:d563e74f0ae9 142 for(i = 0; i < 504; i++) { // 48 x 84 bits = 504 bytes
eencae 0:d563e74f0ae9 143 spi->write(0x00); // send 0's
eencae 0:d563e74f0ae9 144 }
eencae 0:d563e74f0ae9 145 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 146
eencae 0:d563e74f0ae9 147 }
eencae 0:d563e74f0ae9 148
eencae 14:520a02fc12aa 149 // function to set the XY address in RAM for subsequenct data write
eencae 0:d563e74f0ae9 150 void N5110::setXYAddress(int x, int y)
eencae 0:d563e74f0ae9 151 {
eencae 0:d563e74f0ae9 152 // check whether address is in range
eencae 0:d563e74f0ae9 153 if (x > 83)
eencae 0:d563e74f0ae9 154 x=83;
eencae 0:d563e74f0ae9 155 if (y > 5)
eencae 0:d563e74f0ae9 156 y=5;
eencae 3:f90dd1042d17 157 if (x < 0)
eencae 3:f90dd1042d17 158 x=0;
eencae 3:f90dd1042d17 159 if (y < 0)
eencae 3:f90dd1042d17 160 y=0;
eencae 0:d563e74f0ae9 161
eencae 3:f90dd1042d17 162 sendCommand(0x80 | x); // send addresses to display with relevant mask
eencae 0:d563e74f0ae9 163 sendCommand(0x40 | y);
eencae 0:d563e74f0ae9 164 }
eencae 0:d563e74f0ae9 165
eencae 6:adb79338d40f 166 // These functions are used to set, clear and get the value of pixels in the display
eencae 6:adb79338d40f 167 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
eencae 6:adb79338d40f 168 // function must be called after set and clear in order to update the display
eencae 0:d563e74f0ae9 169 void N5110::setPixel(int x, int y)
eencae 0:d563e74f0ae9 170 {
eencae 6:adb79338d40f 171 // calculate bank and shift 1 to required position in the data byte
eencae 0:d563e74f0ae9 172 buffer[x][y/8] |= (1 << y%8);
eencae 0:d563e74f0ae9 173 }
eencae 0:d563e74f0ae9 174
eencae 0:d563e74f0ae9 175 void N5110::clearPixel(int x, int y)
eencae 0:d563e74f0ae9 176 {
eencae 0:d563e74f0ae9 177 // calculate bank and shift 1 to required position (using bit clear)
eencae 0:d563e74f0ae9 178 buffer[x][y/8] &= ~(1 << y%8);
eencae 0:d563e74f0ae9 179 }
eencae 0:d563e74f0ae9 180
eencae 7:3010f24e0a81 181 int N5110::getPixel(int x, int y)
eencae 0:d563e74f0ae9 182 {
eencae 0:d563e74f0ae9 183 // return relevant bank and mask required bit
eencae 7:3010f24e0a81 184 return (int) buffer[x][y/8] & (1 << y%8);
eencae 0:d563e74f0ae9 185
eencae 0:d563e74f0ae9 186 }
eencae 0:d563e74f0ae9 187
eencae 6:adb79338d40f 188 // function to refresh the display
eencae 6:adb79338d40f 189 void N5110::refresh()
eencae 0:d563e74f0ae9 190 {
eencae 0:d563e74f0ae9 191 int i,j;
eencae 14:520a02fc12aa 192
eencae 7:3010f24e0a81 193 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
eencae 7:3010f24e0a81 194 // address auto increments after printing string, so buffer[0][0] will not coincide
eencae 7:3010f24e0a81 195 // with top-left pixel after priting string
eencae 14:520a02fc12aa 196
eencae 0:d563e74f0ae9 197 sce->write(0); //set CE low to begin frame
eencae 0:d563e74f0ae9 198
eencae 0:d563e74f0ae9 199 for(j = 0; j < 6; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:d563e74f0ae9 200 for(i = 0; i < 84; i++) {
eencae 0:d563e74f0ae9 201 spi->write(buffer[i][j]); // send buffer
eencae 0:d563e74f0ae9 202 }
eencae 0:d563e74f0ae9 203 }
eencae 0:d563e74f0ae9 204 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 205
eencae 0:d563e74f0ae9 206 }
eencae 0:d563e74f0ae9 207
eencae 6:adb79338d40f 208 // fills the buffer with random bytes. Can be used to test the display.
eencae 6:adb79338d40f 209 // The rand() function isn't seeded so it probably creates the same pattern everytime
eencae 0:d563e74f0ae9 210 void N5110::randomiseBuffer()
eencae 0:d563e74f0ae9 211 {
eencae 0:d563e74f0ae9 212 int i,j;
eencae 0:d563e74f0ae9 213 for(j = 0; j < 6; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:d563e74f0ae9 214 for(i = 0; i < 84; i++) {
eencae 0:d563e74f0ae9 215 buffer[i][j] = rand()%256; // generate random byte
eencae 0:d563e74f0ae9 216 }
eencae 0:d563e74f0ae9 217 }
eencae 0:d563e74f0ae9 218
eencae 0:d563e74f0ae9 219 }
eencae 0:d563e74f0ae9 220
eencae 0:d563e74f0ae9 221 // function to print 5x7 font
eencae 14:520a02fc12aa 222 void N5110::printChar(char c,int x,int y)
eencae 0:d563e74f0ae9 223 {
eencae 14:520a02fc12aa 224 for (int i = 0; i < 5 ; i++ ) {
eencae 14:520a02fc12aa 225 buffer[x+i][y] = font5x7[(c - 32)*5 + i];
eencae 14:520a02fc12aa 226 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
eencae 0:d563e74f0ae9 227 }
eencae 14:520a02fc12aa 228
eencae 14:520a02fc12aa 229 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
eencae 0:d563e74f0ae9 230 }
eencae 0:d563e74f0ae9 231
eencae 0:d563e74f0ae9 232 // function to print string at specified position
eencae 0:d563e74f0ae9 233 void N5110::printString(const char * str,int x,int y)
eencae 0:d563e74f0ae9 234 {
eencae 0:d563e74f0ae9 235 int n = 0 ; // counter for number of characters in string
eencae 0:d563e74f0ae9 236 // loop through string and print character
eencae 0:d563e74f0ae9 237 while(*str) {
eencae 0:d563e74f0ae9 238
eencae 14:520a02fc12aa 239 // writes the character bitmap data to the buffer, so that
eencae 9:7701f0126ba7 240 // text and pixels can be displayed at the same time
eencae 9:7701f0126ba7 241 for (int i = 0; i < 5 ; i++ ) {
eencae 9:7701f0126ba7 242 buffer[x+i+n*6][y] = font5x7[(*str - 32)*5 + i];
eencae 9:7701f0126ba7 243 }
eencae 14:520a02fc12aa 244
eencae 0:d563e74f0ae9 245 str++; // go to next character in string
eencae 0:d563e74f0ae9 246 n++; // increment index
eencae 0:d563e74f0ae9 247 }
eencae 14:520a02fc12aa 248
eencae 9:7701f0126ba7 249 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
eencae 0:d563e74f0ae9 250
eencae 0:d563e74f0ae9 251 }
eencae 0:d563e74f0ae9 252
eencae 6:adb79338d40f 253 // function to clear the screen
eencae 0:d563e74f0ae9 254 void N5110::clear()
eencae 0:d563e74f0ae9 255 {
eencae 6:adb79338d40f 256 clearBuffer(); // clear the buffer then call the refresh function
eencae 6:adb79338d40f 257 refresh();
eencae 0:d563e74f0ae9 258 }
eencae 0:d563e74f0ae9 259
eencae 6:adb79338d40f 260 // function to clear the buffer
eencae 0:d563e74f0ae9 261 void N5110::clearBuffer()
eencae 0:d563e74f0ae9 262 {
eencae 0:d563e74f0ae9 263 int i,j;
eencae 6:adb79338d40f 264 for (i=0; i<84; i++) { // loop through the banks and set the buffer to 0
eencae 0:d563e74f0ae9 265 for (j=0; j<6; j++) {
eencae 0:d563e74f0ae9 266 buffer[i][j]=0;
eencae 0:d563e74f0ae9 267 }
eencae 0:d563e74f0ae9 268 }
eencae 8:40abe5736eca 269 }
eencae 8:40abe5736eca 270
eencae 8:40abe5736eca 271 // function to plot array on display
eencae 14:520a02fc12aa 272 void N5110::plotArray(float array[])
eencae 14:520a02fc12aa 273 {
eencae 14:520a02fc12aa 274
eencae 8:40abe5736eca 275 int i;
eencae 14:520a02fc12aa 276
eencae 8:40abe5736eca 277 for (i=0; i<84; i++) { // loop through array
eencae 8:40abe5736eca 278 // elements are normalised from 0.0 to 1.0, so multiply
eencae 8:40abe5736eca 279 // by 47 to convert to pixel range, and subtract from 47
eencae 8:40abe5736eca 280 // since top-left is 0,0 in the display geometry
eencae 9:7701f0126ba7 281 setPixel(i,47 - int(array[i]*47.0));
eencae 14:520a02fc12aa 282 }
eencae 14:520a02fc12aa 283
eencae 8:40abe5736eca 284 refresh();
eencae 14:520a02fc12aa 285
eencae 14:520a02fc12aa 286
eencae 0:d563e74f0ae9 287 }