Tuesday, February 20, 2024

PIC16F887 SPI and Nokia 5110 LCD XC8 Example

Overview

The Nokia 5110 LCD module is very popular among electronics hobbyists. This LCD module use the Phillip PCD8544 LCD controller/driver with a display data RAM of 48x84 bit. It can operates between 2.7V and 5.0V DC. Its SPI interface could operate up to 4MBits/s.

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Sample Program using PIC16F887
 

Its slave SPI interface is very easy to control using a dedicated hardware SPI module or even a software SPI bit-banging method.

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Nokia 5110 LCD Module


PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Nokia 5110 LCD Module Back Side

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Panel LPH7366


PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Panel LPH7366

 

Its operating voltage is between +3.3V and +5.0V DC, suitable for most of DIY hobbyist electronics projects.. Its 8 pins are,

  1. RST : Reset (Active Low)
  2. CE   : Chip Enable (Active Low)
  3. DC   : Data(1) or Command(0)
  4. DIN  : Data In 
  5. CLK  : Clock In
  6. VCC  : Positive Supply Voltage
  7. BL    : Back Light
  8. GND : Ground

We can write the data to the display RAM using a vertical or horizontal addressing mode. Using the horizontal addressing mode is very common.

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Instruction Set

The controller accepts command or data via DC pin (logic 1 for data and logic 0 for command).

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Serial Protocol

The microprocessor can transfer the data to this chip using a single byte or multiple bytes transmission mode.

PIC16F887 SPI Interfacing using XC8 C compiler

Using the SPI module of PIC16F887 is very easy. It allow a high speed transmission of data to the LCD without interrupting the micro-controller program.

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Simulating program in Proteus

In this example, the micro-controller send graphic data and text to the LCD repeatedly. 

PIC16F887 SPI and Nokia 5110 LCD XC8 Example
Running Program on PIC16F887 Prototype Board
 

Source Code:

  1.  
  2. #include <xc.h>
  3. #include "config.h"
  4. #include "pcd8544.h"
  5. #include "graphic_84x48.h"
  6.  
  7. #define _XTAL_FREQ 8000000UL
  8.  
  9. void main(void){
  10. OSCCONbits.IRCF=7;
  11. lcd_initialize();
  12. lcd_fill(0x00);
  13.  
  14. while(1){
  15. for(uint16_t i=0;i<sizeof(graphic_84x48);i++)
  16. lcd_write(LCD_D,graphic_84x48[i]);
  17. __delay_ms(5000);
  18. lcd_fill(0);
  19. lcd_text("PIC16F887");
  20. lcd_new_line();
  21. lcd_text("Nokia 5110");
  22. lcd_new_line();
  23. lcd_text("LCD Example");
  24. lcd_new_line();
  25. lcd_text("Using MPLABX");
  26. lcd_text("XC8 Compiler");
  27. lcd_text(" BLOGGER ");
  28. __delay_ms(5000);
  29. lcd_fill(0);
  30. }
  31. }
  32.  

 

I make an PCD8544 driver included in this project. It based on Arduino Playground example.

The PCD8544.h header file:

  1. /* Microchip Technology Inc. and its subsidiaries. You may use this software
  2.  * and any derivatives exclusively with Microchip products.
  3.  *
  4.  * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
  5.  * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
  6.  * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
  7.  * PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
  8.  * WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
  9.  *
  10.  * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
  11.  * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
  12.  * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
  13.  * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
  14.  * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS
  15.  * IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF
  16.  * ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  17.  *
  18.  * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
  19.  * TERMS.
  20.  */
  21.  
  22. /*
  23.  * File:
  24.  * Author:
  25.  * Comments:
  26.  * Revision history:
  27.  */
  28.  
  29. #include <xc.h>
  30. #include "spi.h"
  31.  
  32. #define LCD_C 0
  33. #define LCD_D 1
  34.  
  35. #define LCD_X 84
  36. #define LCD_Y 48
  37.  
  38. #define D_C RC0
  39. #define RST RC1
  40. #define CS RC2
  41. unsigned char char_count=0;
  42.  
  43. void lcd_character(char charactor);
  44. void lcd_fill(unsigned char data);
  45. void lcd_initialize(void);
  46. void lcd_text(char *character);
  47. void lcd_write(char dc,unsigned char _data);
  48. void lcd_new_line();
  49.  
  50. static const char ASCII[][5] =
  51. {
  52. {0x00, 0x00, 0x00, 0x00, 0x00} // 20
  53. ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
  54. ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
  55. ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
  56. ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
  57. ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
  58. ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
  59. ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
  60. ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
  61. ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
  62. ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
  63. ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
  64. ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
  65. ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
  66. ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
  67. ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
  68. ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
  69. ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
  70. ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
  71. ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
  72. ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
  73. ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
  74. ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
  75. ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
  76. ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
  77. ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
  78. ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
  79. ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
  80. ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
  81. ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
  82. ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
  83. ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
  84. ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
  85. ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
  86. ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
  87. ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
  88. ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
  89. ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
  90. ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
  91. ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
  92. ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
  93. ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
  94. ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
  95. ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
  96. ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
  97. ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
  98. ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
  99. ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
  100. ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
  101. ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
  102. ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
  103. ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
  104. ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
  105. ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
  106. ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
  107. ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
  108. ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
  109. ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
  110. ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
  111. ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
  112. ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
  113. ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
  114. ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
  115. ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
  116. ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
  117. ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
  118. ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
  119. ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
  120. ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
  121. ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
  122. ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
  123. ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
  124. ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
  125. ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
  126. ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
  127. ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
  128. ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
  129. ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
  130. ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
  131. ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
  132. ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
  133. ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
  134. ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
  135. ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
  136. ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
  137. ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
  138. ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
  139. ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
  140. ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
  141. ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
  142. ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
  143. ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
  144. ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
  145. ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
  146. ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
  147. ,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f DEL
  148. };

 

The PCD8544.c source file:

  1.  
  2. #include "pcd8544.h"
  3.  
  4. void lcd_character( char character){
  5. int i;
  6. static int x_count=0;
  7. lcd_write(LCD_D,0x00);
  8. for(i=0;i<5;i++){
  9. lcd_write(LCD_D,ASCII[character-0x20][i]);
  10. }
  11. lcd_write(LCD_D,0x00);
  12. x_count+=1;
  13. if(x_count>=12){
  14. x_count=0;
  15. }
  16. char_count=x_count;
  17. }
  18.  
  19. void lcd_fill(unsigned char data){
  20. for(uint16_t i=0;i<LCD_X*LCD_Y/8;i++) lcd_write(LCD_D,data);
  21. }
  22.  
  23. void lcd_new_line(){
  24. int temp;
  25. temp=12-char_count;
  26. if(temp!=0){
  27. for(int i=0;i<temp;i++)
  28. lcd_character(' ');
  29. }
  30. }
  31.  
  32. void lcd_initialize(void){
  33. spi_init();
  34. TRISC0=0;
  35. TRISC1=0;
  36. CS=1;
  37. RST=1;
  38.  
  39. lcd_write(LCD_C,0x21); // LCD Extended Commands
  40. lcd_write(LCD_C,0xB1); // SET LCD CONTRAST
  41. lcd_write(LCD_C,0x04); // set temp coefficient 0x04
  42. lcd_write(LCD_C,0x14); // LCD bias
  43. lcd_write(LCD_C,0x20);
  44. lcd_write(LCD_C,0x0C); // LCD normal Mode
  45.  
  46. /*
  47.   lcd_write(LCD_C,0b00100001);
  48.   lcd_write(LCD_C,0b10010000);
  49.   lcd_write(LCD_C,0b00100000);
  50.   lcd_write(LCD_C,0b00001101);
  51.   */
  52. }
  53.  
  54. void lcd_text( char *character){
  55. while(*character) lcd_character(*character++);
  56. }
  57.  
  58. void lcd_write( char _dc, unsigned char _data){
  59. D_C=_dc;
  60. CS=0;
  61. spi_send(_data);
  62. CS=1;
  63. }
  64.  
  65.  

Click here to download its source file.




Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)