Difference between revisions of "NU32v2: Nokia 5110 LCD"

From Mech
Jump to navigationJump to search
(New page: '''Page Under Construction''' ''NDM 1/10/2011''' This page contains code for using the [http://www.sparkfun.com/products/10168 Nokia 5110 from Sparkfun.] ==Code== /* Use the Sparkfu...)
 
 
(18 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.


== Details ==
/*
[[Media:nokia5110.pdf|Datasheet]]
Use the Sparkfun SPI LCD
Nick Marchuk
12/21/2010


Example schematic when communicating with the NU32v2:
from http://www.arduino.cc/playground/Code/PCD8544
* LCD 1-Vcc -----> NU32v2 3.3V
*/
* LCD 2-GND -----> NU32v2 GND
* LCD 3-SCE -----> NU32v2 E2
#include <stdlib.h>
* LCD 4-RST -----> NU32v2 E1
#include <plib.h>
* 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 ==
// Configuration Bit settings
Code: [[Media:Nokia5110.h|Nokia5110.h]], [[Media:Nokia5110.c|Nokia5110.c]]
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 80 MHz
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
// WDT OFF
// Use Dbg Comm channel 2
// Other options are don't care
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
#pragma config ICESEL = ICS_PGx2


Full example: [[Media:NU32v2_Nokia5110_example.zip|All example code]]
#define GetSystemClock() (80000000ul)
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define SYS_FREQ (80000000L)


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.
/** LED ************************************************************/
#define mInitAllLEDs() LATG |= 0x3000; TRISG &= 0xCFFF;
#define mLED_1 LATGbits.LATG12
#define mLED_2 LATGbits.LATG13


Nokia5110.c contains the following functions:
#define mGetLED_1() mLED_1
* LcdCharacter - used to write an individual ASCII character
#define mGetLED_2() mLED_2
* 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_On() mLED_1 = 0; // low
#define mLED_2_On() mLED_2 = 0; // low


Initialize and clear the LCD:
#define mLED_1_Off() mLED_1 = 1; // high
<code><pre>
#define mLED_2_Off() mLED_2 = 1; // high
LcdInitialize();
LcdClear();
#define mLED_1_Toggle() mLED_1 = !mLED_1;
</pre></code>
#define mLED_2_Toggle() mLED_2 = !mLED_2;


Go to the leftmost side of the screen on the second line and write 'Hello'
<code><pre>
gotoXY(0,1);
LcdString("Hello");
</pre></code>


Write the value of a variable:
#define mInitMotor() LATD |= 0x0000; TRISD &= 0xFFF9;
<code><pre>
#define mDir LATDbits.LATD1
char str[5];
#define mEn LATDbits.LATD2
sprintf(str, "i=%d", i);
#define mDir_Low() mDir = 0; // low
LcdString(str);
#define mDirHigh() mDir = 1; // high
</pre></code>
#define mEn_Low() mEn = 0; // low
#define mEn_High() mEn = 1; // high


Turn on a pixel at (20,35):
<code><pre>
setPixel(20,35,1);
</pre></code>


== More Information ==
// The desired rs232 BaudRate
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.
#define DESIRED_BAUDRATE (115200)//(1000000)//(115200)

// general functions
void init_serial();
void WriteString(const char *string);
void PutCharacter(const char character);

// finger position variables
char RS232_Out_Buffer[32];

// LCD variables
#define mInitLCDPins() LATE |= 0x0000; TRISE &= 0xFFF8;
#define mPIN_SCE LATEbits.LATE2 // LCD CS .... Pin 3
#define mPIN_RESET LATEbits.LATE1 // LCD RST .... Pin 1
#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

// lcd functions
void LcdCharacter(char);
void LcdClear(void);
void LcdInitialise(void);
void LcdString(char *); //void LcdString(char *characters)
void LcdWrite(char, char);
void gotoXY(int, int);
void drawLine(void);

static const char ASCII[96][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00} // 20 (space)
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{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]

unsigned short int channel4; // conversion result as read from result buffer
unsigned short int channel5; // conversion result as read from result buffer


// 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 serial port and interrupt
init_serial();

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

LcdInitialise();
LcdClear();

// configure and enable the ADC
CloseADC10(); // ensure the ADC is off before setting the configuration

// define setup parameters for OpenADC10
// Turn module on | output in integer | trigger mode auto | enable autosample
#define PARAM1 ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON

// define setup parameters for OpenADC10
// ADC ref external | disable offset test | enable scan mode | perform 2 samples | use one buffer | use MUXA mode
// note: to read X number of pins you must set ADC_SAMPLES_PER_INT_X
#define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF

// define setup parameters for OpenADC10
// use ADC internal clock | set sample time
#define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15

// define setup parameters for OpenADC10
// set AN4 and AN5
#define PARAM4 ENABLE_AN4_ANA | ENABLE_AN5_ANA

// define setup parameters for OpenADC10
// do not assign channels to scan
#define PARAM5 SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15

// use ground as neg ref for A
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // use ground as the negative reference
OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above

EnableADC10(); // Enable the ADC

while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers



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) {
channel4 = ReadADC10(0); // read the result of channel 4
sprintf(RS232_Out_Buffer,"a=%d",channel4);
gotoXY(25,4);
LcdString(RS232_Out_Buffer);
}

return 0;
} // end main

// init serial
void init_serial() {
int pbClk;
// Configure the system performance
pbClk = SYSTEMConfigPerformance(SYS_FREQ);

UARTConfigure(UART2A, UART_ENABLE_PINS_TX_RX_ONLY);
UARTSetFifoMode(UART2A, UART_INTERRUPT_ON_TX_DONE | UART_INTERRUPT_ON_RX_NOT_EMPTY);
UARTSetLineControl(UART2A, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
UARTSetDataRate(UART2A, GetPeripheralClock(), DESIRED_BAUDRATE);
UARTEnable(UART2A, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

// Configure UART2A RX Interrupt
INTEnable(INT_U2ARX, INT_ENABLED);
INTSetVectorPriority(INT_UART_2A_VECTOR, INT_PRIORITY_LEVEL_2);
INTSetVectorSubPriority(INT_UART_2A_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
} // end init serial

// write string
void WriteString(const char *string) {
while(*string != '\0') {
while(!UARTTransmitterIsReady(UART2A));

UARTSendDataByte(UART2A, *string);

string++;

while(!UARTTransmissionHasCompleted(UART2A));
}
} // end write string

// put character
void PutCharacter(const char character) {
while(!UARTTransmitterIsReady(UART2A));

UARTSendDataByte(UART2A, character);

while(!UARTTransmissionHasCompleted(UART2A));
} // end put character


// UART 2A interrupt handler, priority level 2
void __ISR(_UART_2A_VECTOR, ipl2) IntUart2AHandler(void) {
// Is this an RX interrupt?
if(INTGetFlag(INT_SOURCE_UART_RX(UART2A))){
// Clear the RX interrupt Flag
INTClearFlag(INT_SOURCE_UART_RX(UART2A));

// Echo what we just received
//PutCharacter(UARTGetDataByte(UART2A));

if(UARTGetDataByte(UART2A)=='a') {
//
}
}

// We don't care about TX interrupt
if(INTGetFlag(INT_SOURCE_UART_TX(UART2A))) {
INTClearFlag(INT_SOURCE_UART_TX(UART2A));
}
} // end uart2 int



///////////////////////////////////////////////////////////////////////////////////////
///////// 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);
}
}

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.