====== Nokia 5110 LCD ======
Datasheet - {{::nokia5510lcd_datasheet.pdf|}}
This is the datasheet for the board itself, with the pinout and a few other important details.
{{:datasheet.jpg |}}
===== Code to Get Started =====
#include
#include "PCD8544.h"
volatile unsigned int adc_val;
char ADC_Str[8];
char *convertADC(int val,int dec_place) {
int digit;
int cVal;
char *ptr;
int tens;
ptr = ADC_Str;
cVal = val;
digit = 1000;
while(digit>=1) {
if(dec_place == digit) {
*(ptr++) = '.'; // Add a decimal place if given
}
if(digit > cVal) {
tens = 0;
} else {
tens = cVal / digit;
}
*(ptr++) = '0' + tens;
cVal -= (tens * digit);
digit /= 10;
}
*ptr = 0; // Terminate the string
return ADC_Str;
}
void main(void) {
unsigned long volts;
unsigned long degrees;
WDTCTL = WDTPW + WDTHOLD;
LCD_init();
while(1) {
/* **************************************************************************
* Write out the Temperature ADC Values
*
*/
LCD_gotoXY(0,0);
LCD_writeString("Temp :");
ADC10CTL0 &= ~ENC; // Switch off ADC.. (Can't set if enabled)
ADC10CTL1 = INCH_10 + ADC10DIV_0; // Select Temperature channel and Div by 1 clock
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
// Range to VRef+, Max Sample and hold time
// turn on reference, turn on the ADC and enable Interrupts
__delay_cycles(40); // Allow time for the reference voltage to settle
ADC10CTL0 |= ENC + ADC10SC; // enable the encoder and start conversion
__bis_SR_register(CPUOFF + GIE); // Turn off the CPU and allow interrupts (ISR turns on CPU)
adc_val = ADC10MEM; // Put the ADC value into var
LCD_writeString(convertADC(adc_val,-1)); // Write out the converted calue
LCD_gotoXY(28,1);
LCD_writeChar('(');
degrees = adc_val - 673;
degrees *= 4230;
degrees /= 1024;
// degrees = ((adc_val - 673) * 4230) / 1024;
LCD_writeString(convertADC(degrees,1));
LCD_writeChar(0x7f);
LCD_writeString("C)");
/* **************************************************************************
* Write out the VCC/2 ADC Values
*
*/
LCD_gotoXY(0,2);
LCD_writeString("VCC :");
ADC10CTL0 &= ~ENC; // Switch off ADC.. (Can't set if enabled)
ADC10CTL1 = INCH_11; // Select VCC/2
// ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
ADC10CTL0 = SREF_1 + REF2_5V + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
// Range to 2.5V reference, Max Sample and hold time
// turn on reference, turn on the ADC and enable Interrupts
__delay_cycles(140); // Allow time for the reference voltage to settle
ADC10CTL0 |= ENC + ADC10SC; // enable the encoder and start conversion
__bis_SR_register(CPUOFF + GIE); // Turn off the CPU and allow interrupts (ISR turns on CPU)
adc_val = ADC10MEM; // Put the ADC value into var
LCD_writeString(convertADC(adc_val,-1)); // Write out the converted calue
LCD_gotoXY(28,3); // Move to next line
LCD_writeChar('(');
volts = adc_val;
volts *= 5000;
volts /= 1023;
LCD_writeString(convertADC(volts,100));
LCD_writeString("V)");
/* **************************************************************************
* Write out the POT ADC Values (Pin 1.3)
*
*/
LCD_gotoXY(0,4); // Move to next line
LCD_writeString("POT :");
ADC10CTL0 &= ~ENC; // Turn off ADC so we can change settings
ADC10CTL1 = INCH_3 + ADC10DIV_0; // Channel 3 (pin 1.3)
ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE; // Shorter sample and hold time, turn on ADC and use interrupts
ADC10AE0 |= BIT3; // Enable bit 3
ADC10CTL0 |= ENC + ADC10SC; // Start the conversion
__bis_SR_register(CPUOFF + GIE); // Turn off CPU and enable interrupts (ISR re-enables CPU)
adc_val = ADC10MEM;
LCD_writeString(convertADC(adc_val,-1));
}
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
__bic_SR_register_on_exit(CPUOFF);
}
#include
#include "PCD8544.h"
static const char ASCII[][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{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 Deg Symbol
};
#define LCD_SCE BIT0 // Serial Chip Enable
#define LCD_RST BIT7 // Reset line
#define LCD_DC BIT4 // Data or Command input
#define LCD_SDI BIT5 // Serial Data In
#define LCD_SCLK BIT6 // Serial Data Clock
#define LCD_CMD 0 // Writing a CMD
#define LCD_DATA 1 // Writing Data
volatile char LCD_IsReverse = 0; // Are we writing out inversed characters?
void LCD_init(void) {
P1SEL &= ~(LCD_SCE + LCD_RST + LCD_DC + LCD_SDI + LCD_SCLK); // Indicate each pin is IO
P1DIR = LCD_SCE + LCD_RST + LCD_DC + LCD_SDI + LCD_SCLK; // Set each pin for output
P1OUT &= ~LCD_SCE; // Disable chip input
P1OUT |= LCD_RST; // Clear the reset
P1OUT &= ~LCD_RST; // Reset the LCD Chip
P1OUT |= LCD_RST; // Clear the reset
P1OUT &= ~LCD_SCLK; // Set Clock line high
P1OUT |= LCD_SCLK; // Set Clock line high
P1OUT |= LCD_SCE; // And clear chip enabled
LCD_write(LCD_CMD, 0x21); // LCD Extended Commands
LCD_write(LCD_CMD, 0xBF); // Set LCD Vop (Contrast)
LCD_write(LCD_CMD, 0x06); // Set the Temp coefficient
LCD_write(LCD_CMD, 0x13); // LCD Bias mode 1:48
LCD_write(LCD_CMD, 0x20); // LCD in Normal mode (non inversed)
LCD_write(LCD_CMD, 0x08); // ** TODO ** Unsure of this command here
LCD_write(LCD_CMD, 0x0C); // ** TODO ** Unsure of this command here
LCD_gotoXY(0,0); // Jump to top left of display
LCD_clear();
}
void LCD_writeString(const char *str) {
while(*str) {
LCD_writeChar(*str++);
}
}
void LCD_writeChar(char c) {
unsigned char i;
LCD_write(LCD_DATA,0); // blank vert col before char
for(i=0; i<5; i++) {
LCD_write(LCD_DATA,ASCII[c - 0x20][i]);
}
LCD_write(LCD_DATA,0); // Blank vert col after char
}
void LCD_write(unsigned char dc, char c) {
if(dc == LCD_DATA) {
P1OUT |= LCD_DC; // DC Line to high if writing data
if(LCD_IsReverse == 1) {
c = ~c;
}
} else {
P1OUT &= ~LCD_DC; // Else low for CMD
}
P1OUT &= ~LCD_SCE; // Pull Chip select low
unsigned char b = 128;
while(b != 0) {
if(c & b) {
P1OUT |= LCD_SDI; // Writing a 1 raise SDI
} else {
P1OUT &= ~LCD_SDI; // 0 is SDI to low
}
P1OUT &= ~LCD_SCLK; // Pulse clock line low (latches the serial data)
P1OUT |= LCD_SCLK;
b >>= 1; // shift to next bit
}
P1OUT |= LCD_SCE; // SCE High = Un select chip
}
void LCD_gotoXY(unsigned char x, unsigned char y) {
LCD_write(LCD_CMD, 0x80 | x);
LCD_write(LCD_CMD, 0x40 | y);
}
void LCD_clear(void) {
unsigned char x,y;
for(y=0; y< LCD_HEIGHT >> 3; y++) {
for(x=0; x< LCD_WIDTH; x++) {
LCD_write(LCD_DATA, 0x00);
}
}
}
#ifndef PCD8544_H_
#define PCD8544_H_
void LCD_write(unsigned char dc, char c);
void LCD_writeChar(char c);
void LCD_writeString(const char *str);
void LCD_gotoXY(unsigned char x, unsigned char y);
void LCD_clear(void);
void LCD_init(void);
#define LCD_WIDTH 84 // 84 Pixels width
#define LCD_HEIGHT 48 // 48 Pixels height
#endif /*PCD8544_H_*/