Difference between revisions of "NU32v2: Nokia 5110 LCD"

From Mech
Jump to navigationJump to search
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''THIS PAGE REFERS TO A PRE-RELEASE VERSION OF THE NU32 PIC32 DEVELOPMENT BOARD. FOR INFORMATION, SAMPLE CODE, AND VIDEOS RELATED TO THE PRODUCTION VERSION (2016 AND LATER), AND TO THE CORRESPONDING BOOK "EMBEDDED COMPUTING AND MECHATRONICS WITH THE PIC32 MICROCONTROLLER," VISIT [[NU32|THE NU32 PAGE]].'''
'''Page Under Construction'''


'''NDM 1/10/2011'''


[[Image:nu32v2_nokia5110_example.jpg|thumb|300px|The Sparkfun Nokia 5110 controlled by the NU32v2.|center]]


This page contains code for using the [http://www.sparkfun.com/products/10168 Nokia 5110 from Sparkfun.]
The [http://www.sparkfun.com/products/10168 Nokia 5110 from Sparkfun] is a 84 x 48 pixel monochrome LCD and breakout board. It is controlled using SPI communication and several digital outputs.




==Code==
== Overview ==
An LCD is a convenient tool for communication data using text. The Nokia 5110 provides 6 rows of 12 characters of text, or can be used to draw in a 84 x 48 pixel space. The contrast is digitally controlled and 4 white LEDs behind the LCD provide a backlight.


The LCD requires five communication pins from a microcontroller: SPI CLK and SDO, and three digital outputs. The LCD is powered with 3.3V.
<code><pre>
/*
Use the Sparkfun SPI LCD
Nick Marchuk
12/21/2010


== Details ==
from http://www.arduino.cc/playground/Code/PCD8544
[[Media:nokia5110.pdf|Datasheet]]
*/
#include <stdlib.h>
#include <plib.h>


Example schematic when communicating with the NU32v2:
// Configuration Bit settings
* LCD 1-Vcc -----> NU32v2 3.3V
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
* LCD 2-GND -----> NU32v2 GND
// PBCLK = 80 MHz
* LCD 3-SCE -----> NU32v2 E2
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
* LCD 4-RST -----> NU32v2 E1
// WDT OFF
* LCD 5-D/C -----> NU32v2 E0
// Use Dbg Comm channel 2
* LCD 6-DNK(MOSI) -----> NU32v2 F8 (SDO3)
// Other options are don't care
* LCD 7-SCLK -----> NU32v2 D15 (SCK3)
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
* LCD 8-LED -----> 330 ohm -----> 5V
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
** Note: hooking up 8-LED is only required if you want to use the backlight
#pragma config ICESEL = ICS_PGx2


== Library Functions ==
#define GetSystemClock() (80000000ul)
Code: [[Media:Nokia5110.h|Nokia5110.h]], [[Media:Nokia5110.c|Nokia5110.c]]
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define SYS_FREQ (80000000L)


Full example: [[Media:NU32v2_Nokia5110_example.zip|All example code]]
/** LED ************************************************************/
#define mInitAllLEDs() LATG |= 0x3000; TRISG &= 0xCFFF;
#define mLED_1 LATGbits.LATG12
#define mLED_2 LATGbits.LATG13


Nokia5110.h sets up control pins on E0, E1 and E2. These may be changed if desired. The file also contains function prototypes, constants, and a 96 x 5 element lookup array of ASCII characters.
#define mGetLED_1() mLED_1
#define mGetLED_2() mLED_2


Nokia5110.c contains the following functions:
#define mLED_1_On() mLED_1 = 0; // low
* LcdCharacter - used to write an individual ASCII character
#define mLED_2_On() mLED_2 = 0; // low
* LcdClear - clears the entire LCD
* LcdInitialize - Initializes SPI3 (can be changed if desired) and sends the startup commands to the LCD
** The second command sent (LCD Vop) sets the contrast of the LCD and can be altered for more or less contrast
* LcdString - writes a string of characters to the LCD
* LcdWrite - sends individual commands to the LCD
** Sending commands before the LCD is ready for them will make the LCD miss them, so 1000 Nop()s are called between commands
* gotoXY - places the cursor at an x pixel (0-84) and y character (0-5)
* setPixel - turns on a pixel at x (0-84) and y (0-48)


== Sample Code ==
#define mLED_1_Off() mLED_1 = 1; // high
#define mLED_2_Off() mLED_2 = 1; // high
#define mLED_1_Toggle() mLED_1 = !mLED_1;
#define mLED_2_Toggle() mLED_2 = !mLED_2;


Initialize and clear the LCD:
char Out_Buffer[32];
<code><pre>
LcdInitialize();
LcdClear();
</pre></code>


Go to the leftmost side of the screen on the second line and write 'Hello'
// LCD variables
<code><pre>
#define mInitLCDPins() LATE |= 0x0000; TRISE &= 0xFFF8;
gotoXY(0,1);
#define mPIN_SCE LATEbits.LATE2 // LCD CS .... Pin 3
LcdString("Hello");
#define mPIN_RESET LATEbits.LATE1 // LCD RST .... Pin 1
</pre></code>
#define mPIN_DC LATEbits.LATE0 // LCD Dat/Com. Pin 5
#define mSCE_Low() mPIN_SCE = 0; // low
#define mSCE_High() mPIN_SCE = 1; // high
#define mRESET_Low() mPIN_RESET = 0; // low
#define mRESET_High() mPIN_RESET = 1; // high
#define mDC_Low() mPIN_DC = 0; // low
#define mDC_High() mPIN_DC = 1; // high
//#define PIN_SDIN 4 // LCD SPIDat . Pin 6
//#define PIN_SCLK 3 // LCD SPIClk . Pin 4
// LCD Gnd .... Pin 2
// LCD Vcc .... Pin 8
// LCD Vlcd ... Pin 7
#define LCD_C 0
#define LCD_D 1
#define LCD_X 84
#define LCD_Y 48
//#define LCD_CMD 0


Write the value of a variable:
// lcd functions
<code><pre>
void LcdCharacter(char);
char str[5];
void LcdClear(void);
sprintf(str, "i=%d", i);
void LcdInitialise(void);
void LcdString(char *); //void LcdString(char *characters)
LcdString(str);
</pre></code>
void LcdWrite(char, char);
void gotoXY(int, int);
void drawLine(void);


Turn on a pixel at (20,35):
static const char ASCII[96][5] = {
<code><pre>
{0x00, 0x00, 0x00, 0x00, 0x00} // 20 (space)
setPixel(20,35,1);
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
</pre></code>
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f ?
}; // end char ASCII[96][5]


== More Information ==

The sample code in [[Media:NU32v2_Nokia5110_example.zip|All example code]] will create the image at the top of this page. Sending the NU32v2 an 'a' over serial will clear the LCD.
// main
int main(void) {
unsigned int pb_clock;
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
// configure for multi-vectored mode
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);

// enable multi-vector interrupts
INTEnableSystemMultiVectoredInt();

// initialize the leds
mInitAllLEDs();
mLED_1_Off(); // low
mLED_2_On(); // low

LcdInitialise();
LcdClear();

int a,b;
char Str[15];
// Draw a Box
//for(b=1000; b>0; b--){
//drawLine();
//for(a=0; a<=5 ; a++){
gotoXY(0,1);
// Put text in Box
LcdString("1 Test1");
gotoXY(0,0);
LcdString("012345678901");
gotoXY(25,2);
LcdString("Test2");
gotoXY(16,3);
LcdString("Test3");

gotoXY(0,2);
LcdString("2");
gotoXY(0,3);
LcdString("3");
gotoXY(0,4);
LcdString("4");
gotoXY(0,5);
LcdString("5");

/*
gotoXY(24,3);
LcdCharacter('H');
LcdCharacter('E');
LcdCharacter('L');
LcdCharacter('L');
LcdCharacter('O');
LcdCharacter(' ');
LcdCharacter('=');
// Draw + at this position
gotoXY(10,3);
LcdCharacter('=');
//delay(500);
gotoXY(24,3);
LcdCharacter('h');
LcdCharacter('e');
LcdCharacter('l');
LcdCharacter('l');
LcdCharacter('o');
LcdCharacter(' ');
LcdCharacter('-');
// Draw - at this position
gotoXY(10,3);
LcdCharacter('-');
*/

mLED_1_On();


while(1) {
sprintf(Out_Buffer,"a=%d",somevariable);
gotoXY(25,4);
LcdString(Out_Buffer);
}

return 0;
} // end main


///////////////////////////////////////////////////////////////////////////////////////
///////// LCD Functions /////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

void LcdCharacter(char character)
{
LcdWrite(LCD_D, 0x00);
int index;
for (index = 0; index < 5; index++)
{
LcdWrite(LCD_D, ASCII[character - 0x20][index]);
//LcdWrite(LCD_D, ASCII[character - 0x20 + index]);
}
LcdWrite(LCD_D, 0x00);
}

void LcdClear(void)
{
int index;
for (index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D, 0x00);
}
}

void LcdInitialise(void)
{
//pinMode(PIN_SCE, OUTPUT);
//pinMode(PIN_RESET, OUTPUT);
//pinMode(PIN_DC, OUTPUT);
//pinMode(PIN_SDIN, OUTPUT);
//pinMode(PIN_SCLK, OUTPUT);

mInitLCDPins();
SpiChnOpen(SPI_CHANNEL1A, SPI_OPEN_MSTEN|SPI_OPEN_MODE8|SPI_OPEN_ON, GetPeripheralClock()/100000); // will open SPI3 and set the bit rate to .1MHz

//digitalWrite(PIN_RESET, LOW);
// delay(1);
//digitalWrite(PIN_RESET, HIGH);

mRESET_Low();
mRESET_High();

mSCE_High();

LcdWrite(LCD_C, 0x21 ); // LCD Extended Commands.
LcdWrite(LCD_C, 185 ); // Set LCD Vop (Contrast). //B1
LcdWrite(LCD_C, 0x04 ); // Set Temp coefficent. //0x04
LcdWrite(LCD_C, 0x14 ); // LCD bias mode 1:48. //0x13
LcdWrite(LCD_C, 0x0C ); // LCD in normal mode. 0x0d for inverse
LcdWrite(LCD_C, 0x20);
LcdWrite(LCD_C, 0x0C);
}

void LcdString(char *characters)
{
while (*characters)
{
LcdCharacter(*characters++);
}
}

void LcdWrite(char dc, char data)
{
//digitalWrite(PIN_DC, dc);
//digitalWrite(PIN_SCE, LOW);

if(dc) {
mDC_High();
}
else {
mDC_Low();
}
mSCE_Low();

//shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
SpiChnPutC(SPI_CHANNEL1A, data);

int i;
for (i=0; i<10000; i++) {
Nop();
}

//digitalWrite(PIN_SCE, HIGH);

mSCE_High();
}

// gotoXY routine to position cursor
// x - range: 0 to 84
// y - range: 0 to 5
void gotoXY(int x, int y)
{
LcdWrite( 0, 0x80 | x); // Column.
LcdWrite( 0, 0x40 | y); // Row.
}

void drawLine(void)
{
unsigned char j;
for(j=0; j<84; j++) // top
{
gotoXY (j,0);
LcdWrite (1,0x01);
}
for(j=0; j<84; j++) //Bottom
{
gotoXY (j,5);
LcdWrite (1,0x80);
}

for(j=0; j<6; j++) // Right
{
gotoXY (83,j);
LcdWrite (1,0xff);
}
for(j=0; j<6; j++) // Left
{
gotoXY (0,j);
LcdWrite (1,0xff);
}
}

</pre></code>

Latest revision as of 06:28, 16 January 2016

THIS PAGE REFERS TO A PRE-RELEASE VERSION OF THE NU32 PIC32 DEVELOPMENT BOARD. FOR INFORMATION, SAMPLE CODE, AND VIDEOS RELATED TO THE PRODUCTION VERSION (2016 AND LATER), AND TO THE CORRESPONDING BOOK "EMBEDDED COMPUTING AND MECHATRONICS WITH THE PIC32 MICROCONTROLLER," VISIT THE NU32 PAGE.


The Sparkfun Nokia 5110 controlled by the NU32v2.

The Nokia 5110 from Sparkfun is a 84 x 48 pixel monochrome LCD and breakout board. It is controlled using SPI communication and several digital outputs.


Overview

An LCD is a convenient tool for communication data using text. The Nokia 5110 provides 6 rows of 12 characters of text, or can be used to draw in a 84 x 48 pixel space. The contrast is digitally controlled and 4 white LEDs behind the LCD provide a backlight.

The LCD requires five communication pins from a microcontroller: SPI CLK and SDO, and three digital outputs. The LCD is powered with 3.3V.

Details

Datasheet

Example schematic when communicating with the NU32v2:

  • LCD 1-Vcc -----> NU32v2 3.3V
  • LCD 2-GND -----> NU32v2 GND
  • LCD 3-SCE -----> NU32v2 E2
  • LCD 4-RST -----> NU32v2 E1
  • LCD 5-D/C -----> NU32v2 E0
  • LCD 6-DNK(MOSI) -----> NU32v2 F8 (SDO3)
  • LCD 7-SCLK -----> NU32v2 D15 (SCK3)
  • LCD 8-LED -----> 330 ohm -----> 5V
    • Note: hooking up 8-LED is only required if you want to use the backlight

Library Functions

Code: Nokia5110.h, Nokia5110.c

Full example: All example code

Nokia5110.h sets up control pins on E0, E1 and E2. These may be changed if desired. The file also contains function prototypes, constants, and a 96 x 5 element lookup array of ASCII characters.

Nokia5110.c contains the following functions:

  • LcdCharacter - used to write an individual ASCII character
  • LcdClear - clears the entire LCD
  • LcdInitialize - Initializes SPI3 (can be changed if desired) and sends the startup commands to the LCD
    • The second command sent (LCD Vop) sets the contrast of the LCD and can be altered for more or less contrast
  • LcdString - writes a string of characters to the LCD
  • LcdWrite - sends individual commands to the LCD
    • Sending commands before the LCD is ready for them will make the LCD miss them, so 1000 Nop()s are called between commands
  • gotoXY - places the cursor at an x pixel (0-84) and y character (0-5)
  • setPixel - turns on a pixel at x (0-84) and y (0-48)

Sample Code

Initialize and clear the LCD:

  LcdInitialize();
  LcdClear();

Go to the leftmost side of the screen on the second line and write 'Hello'

  gotoXY(0,1);
  LcdString("Hello");

Write the value of a variable:

  char str[5];
  sprintf(str, "i=%d", i);
  LcdString(str);

Turn on a pixel at (20,35):

  setPixel(20,35,1);

More Information

The sample code in All example code will create the image at the top of this page. Sending the NU32v2 an 'a' over serial will clear the LCD.