You are on page 1of 8

CCS does not monitor this forum on a regular basis.

FAQ Forum Help Official CCS Support Search Register


Please do not post bug Reports on this forum. Send them to support@ccsinfo.com
Profile Log in to check your private messages Log in

Nokia 5110 driver

CCS Forum Index -> Code Library

View previous topic :: View next topic

Author Message

pmaggi Nokia 5110 driver


Posted: Sat Aug 22, 2015 4:32 pm

Joined: 05 Jun 2013


Posts: 10
Hi, I found a couple of drivers in this forum for nokia 5110 lcd but all of them were mainly txt drivers. So I wrote this one
that implements graphical functions like drawing pixels, lines, boxes, circles, bars...
It uses a video memory map, so you can have txt and graphics at the same time. First you "draw" everything you want to
show in that memory and then dump it to the lcd.
I hope you enjoy it!.
I uploaded a video of it to youtube: https://www.youtube.com/watch?v=x6TdIBKR3N4&feature=youtu.be

Here is the code:


Code:

///////////////////////////////////////////////////////////////////////////////
// Driver for Nokia 5110 lcd //
// Pablo Maggi - 2015 //
//Conventions about coords. //
// (x,y) means x=0..83 y=0..47 //
// [x,y] means x=0..83 y=0..5 //
// //
//Funtions provided by this driver: //
// //
//nokia_init() initializes the lcd //
//nokia_refresh() dump video memory map to lcd //
//nokia_write_command(c) Sends command c to lcd //
//nokia_write_data(c) Sends data c to lcd //
//nokia_write_dorc(c) Sends data/command to lcd //
//nokia_clean_buffer() initialize video memory map //
//nokia_contrast(contrast) sets lcd contrast (0..127) //
//nokia_gotoxy(x,y) sets cursor [x,y] position on video memory //
// map //
//nokia_printchar(c) draws character c at cursor position on video//
// memory map //
//nokia_printstr(char* m) draws a string of characters at cursor //
// position on memory map. If the string is //
// longer than the lcd width, it continues in //
// next row //
//nokia_plot(x,y,color) Draws a pixel in video memory map at coords. //
// (x,y). It draws it on or off depending on //
// the value of color, 1 or 0 //
//nokia_line(x1,y1,x2,y2,color) Draws a line between (x1,y1) and (x2,y2), on //
// or off depending on color //
//nokia_box(x1,y1,x2,y2,fill,c) Draws a box of corners (x1,y1) and (x2,y2) //
// Fill o empty depending on fill and on or off //
// depending on c //
//nokia_bar(x1,y1,x2,y2,w,c) Draws a bar from (x1,y1) to (x2,y2) with a //
// width of w and on or off depending on c //
//nokia_circle(x,y,r,f,c) Draws a cirle with center on (x,y) and radius//
// r and filled depending on f. On or off //
// depending on c //
///////////////////////////////////////////////////////////////////////////////

//Defino los pines de comunicación entre PIC y LCD


#define nok_sclk PIN_C0 // nokia lcd sclk pin 2
#define nok_sda PIN_C1 // nokia lcd sda pin 3
#define nok_dc PIN_C2 // nokia lcd d/c pin 4
#define nok_cs PIN_C3 // nokia lcd cs pin 5
#define nok_res PIN_C4 // nokia lcd res pin 8

static int8 buffer[84][6]; //defino mapa de memoria de 504 bytes, 84x6


static int8 idx=0,idy=0; //indices del mapa de memoria

char CONST TABLA1 [240] = { // tabla ASCII para LCD NOKIA: 96 filas * 5 bytes= 480
bytes
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
char CONST TABLA2 [240] = {
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 ~
0x78,0x46,0x41,0x46,0x78}; // 7f ¦

//Funciones implementadas
void nokia_init(void); //inicialización del LCD
void nokia_refresh(void); //vuelco el mapa de memoria en el LCD
void nokia_write_command(int8 c); //Escribo comando
void nokia_write_data(int8 c); //escribo dato
void nokia_write_dorc(int8 c); //escritura de dato o comando
void nokia_clean_buffer(void); //inicializado del mapa de memoria
void nokia_contrast(int8 contraste); //seteo contraste del LCD
void nokia_gotoxy(int8 x,int8 y); //posiciono cursor en columna x, fila y
(84,6) en el mapa de memoria
void nokia_printchar(int8 c); //dibujo caracter en la posición actual
void nokia_printstr(char* message); //dibujo una cadena en la posición actual
void nokia_plot(int8 x,int8 y,int8 color); //prende o apaga un pixel segun color
(84,48 pixeles)
void nokia_line(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, int1
color);
void nokia_box(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, int1 fill,
int1 color);
void nokia_bar(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, unsigned
int8 width, int1 color);
void nokia_circle(unsigned int8 x, unsigned int8 y, unsigned int8 radius, int1 fill, int1 color);

/////////////////////////////////////////////////////////////////////////////////////////////////
//Inicialización
void nokia_init() {
nokia_clean_buffer(); //limpio mapa de memoria
output_high(nok_dc); // bytes are stored in the display data ram, address counter,
incremented automatically
output_high(nok_cs); // chip disabled
delay_us(200);
output_low(nok_res);
delay_ms(250);
output_high(nok_res);
nokia_write_command(0x21); //elijo conjunto de instrucciones extendidas
nokia_write_command(0xc2); //Vop
nokia_write_command(0x13); //bias
nokia_write_command(0x20); //modo horizontal de izq. a der., eje X se incrementa
automaticamente,
//0x22 para direccionamiento vertical, también de nuevo en
conjunto de instrucciones normales
nokia_write_command(0x09); //todo ON

delay_ms(50);

nokia_refresh(); //actualizo display

delay_ms(10);

nokia_write_command(0x08); //todo off


delay_ms(10);
nokia_write_command(0x0c); //modo normal
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//limpio el mapa de memoria
void nokia_clean_buffer() {
int8 i,j;
for(j=0;j<6;j++){ //borro el mapa de memoria
for(i=0;i<84;i++){
buffer[i][j]=0x00;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//vuelco mapa de memoria al LCD
void nokia_refresh() {
int8 i,j;
nokia_write_command(0x40);
nokia_write_command(0x80);
for(j=0;j<6;j++){ //mando mapa de memoria al LCD
for(i=0;i<84;i++){
nokia_write_data(buffer[i][j]);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//escribo comando
void nokia_write_command(int8 comando)
{
output_low(nok_dc); //es un comando
output_low(nok_cs); //habilito el chip
nokia_write_dorc(comando);
output_high(nok_cs); //deshabilito el chip
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//escribo dato
void nokia_write_data(int8 dato)
{
output_high(nok_dc); //es un dato
output_low(nok_cs); //habilito el chip
nokia_write_dorc(dato);
output_high(nok_cs); //deshabilito el chip
}
////////////////////////////////////////////////////////////////////////////////////////////////
//mando el dato o comando en forma serial
void nokia_write_dorc(int8 n_dato)
{
int8 caa;
for (caa=8;caa>0;caa--){ //mando MSB primero
output_low(nok_sclk);
delay_us(2);
if ((n_dato&0x80)==0)
output_low(nok_sda);
else
output_high(nok_sda);
output_high(nok_sclk);
delay_us(2);
n_dato = n_dato << 1;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
//posiciono cursor en el byte correspondiente al mapa de memoria para [x,y]
void nokia_gotoxy(int8 x, int8 y)
{
if(x>83)
x=83;
if(y>5)
y=5;
idx=x;
idy=y;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//fijo contraste
void nokia_contrast(int8 contraste)
{
nokia_write_command(0x21); //comandos extendidos del LCD
nokia_write_command(0x80 | contraste); //fijo el Vop del Vop (contraste)
nokia_write_command(0x20); //vuelvo a comandos estandares de LCD y
direccionamiento horizontal
}
///////////////////////////////////////////////////////////////////////////////////////////////
//cargo un caracter en posición actual del mapa de memoria
void nokia_printchar(int8 c)
{
char char_row,char_pos,char_data;

if (c<0x20) return; //verifico que el caracter sea "mostrable"


if (c>0x7f) return;

for (char_row=0;char_row<5;char_row++)
{
if (idx>83){
idx=0;
idy++;
if (idy>5)
idy=0;
}
if (c<0x50){
char_pos=((c-0x20)*5); //uso TABLA1
char_data=TABLA1[(char_pos+char_row)];
}
if (c>0x4f){
char_pos=((c-0x50)*5); //uso TABLA2
char_data=TABLA2[(char_pos+char_row)];
}
buffer[idx][idy]=char_data;
idx++;
}
buffer[idx][idy]=0x00; //dejo 1 byte en blanco para separar caracteres
idx++;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//dibujo un pixel
//(x,y) - coordenadas del pixel
//color - on/off
void nokia_plot(int8 x, int8 y, int1 color) {
int16 offset;
byte data;

if (x > 83) return; //x debe ser menor de 83


if (y > 47) return; //y debe ser menor de 47

offset = y - ((y / 8) * 8);


if (color)
data = (0x01 << offset);
else
data = (0xfe << offset);

nokia_gotoxy(x, (y/8));
if (color)
buffer[idx][idy]=buffer[idx][idy]|data; //hago el OR de lo que hay en la posición del
buffer y el pixel nuevo
else
buffer[idx][idy]=buffer[idx][idy]&data; //hago el AND de lo que hay en la posición del
buffer y el pixe nuevo
}
/////////////////////////////////////////////////////////////////////////
// Dibuja una linea
// (x1, y1) - coordenada de comienzo
// (x2, y2) - coordenada de fin
// color - ON o OFF
void nokia_line(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, int1
color)
{
unsigned int16 dy, dx;
signed int8 addx=1, addy=1;
signed int16 P, diff;

unsigned int8 i=0;


dx = abs((signed int8)(x2 - x1));
dy = abs((signed int8)(y2 - y1));

if(x1 > x2)


addx = -1;
if(y1 > y2)
addy = -1;

if(dx >= dy)


{
dy *= 2;
P = dy - dx;
diff = P - dx;

for(; i<=dx; ++i)


{
nokia_plot(x1, y1, color);

if(P < 0)
{
P += dy;
x1 += addx;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
else
{
dx *= 2;
P = dx - dy;
diff = P - dy;

for(; i<=dy; ++i)


{
nokia_plot(x1, y1, color);

if(P < 0)
{
P += dx;
y1 += addy;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
}
/////////////////////////////////////////////////////////////////////////
// Dibuja un rectangulo
// (x1, y1) - coordenada de inicio
// (x2, y2) - coordenada de fin
// fill - YES/NO
// color - ON/OFF
void nokia_box(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, int1 fill,
int1 color)
{
if(fill)
{
unsigned int8 i, xmin, xmax, ymin, ymax;
if(x1 < x2) // Encuentra x min y max
{
xmin = x1;
xmax = x2;
}
else
{
xmin = x2;
xmax = x1;
}

if(y1 < y2) // Encuentra y min y max


{
ymin = y1;
ymax = y2;
}
else
{
ymin = y2;
ymax = y1;
}

for(; xmin <= xmax; ++xmin)


{
for(i=ymin; i<=ymax; ++i)
{
nokia_plot(xmin, i, color);
}
}
}
else
{
nokia_line(x1, y1, x2, y1, color); // Dibuja los 4 lados
nokia_line(x1, y2, x2, y2, color);
nokia_line(x1, y1, x1, y2, color);
nokia_line(x2, y1, x2, y2, color);
}
}
/////////////////////////////////////////////////////////////////////////
// Dibuja una barra
// (x1, y1) - coordenada de inicio
// (x2, y2) - coordenada de fin
// width - El número de pixels de ancho
// color - ON o OFF
void nokia_bar(unsigned int8 x1, unsigned int8 y1, unsigned int8 x2, unsigned int8 y2, unsigned
int8 width, int1 color)
{
unsigned int8 half_width;
signed int16 dy, dx;
signed int8 addx=1, addy=1, j;
signed int16 P, diff, c1, c2;

unsigned int8 i=0;


dx = abs((signed int8)(x2 - x1));
dy = abs((signed int8)(y2 - y1));

half_width = width/2;
c1 = -(dx*x1 + dy*y1);
c2 = -(dx*x2 + dy*y2);

if(x1 > x2)


{
signed int16 temp;
temp = c1;
c1 = c2;
c2 = temp;
addx = -1;
}
if(y1 > y2)
{
signed int16 temp;
temp = c1;
c1 = c2;
c2 = temp;
addy = -1;
}

if(dx >= dy)


{
P = 2*dy - dx;
diff = P - dx;

for(i=0; i<=dx; ++i)


{
for(j=-half_width; j<half_width+width%2; ++j)
{
nokia_plot(x1, y1+j, color);
}
if(P < 0)
{
P += 2*dy;
x1 += addx;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
else
{
P = 2*dx - dy;
diff = P - dy;

for(i=0; i<=dy; ++i)


{
if(P < 0)
{
P += 2*dx;
y1 += addy;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
for(j=-half_width; j<half_width+width%2; ++j)
{
nokia_plot(x1+j, y1, color);
}
}
}
}
/////////////////////////////////////////////////////////////////////////
// Dibuja un circulo
// (x,y) - centro del circulo
// radius - radio del circulo
// fill - YES/NO
// color - ON/OFF
void nokia_circle(unsigned int8 x, unsigned int8 y, unsigned int8 radius, int1 fill, int1 color)
{
signed int8 a, b, P;

a = 0;
b = radius;
P = 1 - radius;

do
{
if(fill)
{
nokia_line(x-a, y+b, x+a, y+b, color);
nokia_line(x-a, y-b, x+a, y-b, color);
nokia_line(x-b, y+a, x+b, y+a, color);
nokia_line(x-b, y-a, x+b, y-a, color);
}
else
{
nokia_plot(a+x, b+y, color);
nokia_plot(b+x, a+y, color);
nokia_plot(x-a, b+y, color);
nokia_plot(x-b, a+y, color);
nokia_plot(b+x, y-a, color);
nokia_plot(a+x, y-b, color);
nokia_plot(x-a, y-b, color);
nokia_plot(x-b, y-a, color);
}

if(P < 0)
P += 3 + 2 * a++;
else
P += 5 + 2 * (a++ - b--);
} while(a <= b);
}
///////////////////////////////////////////////////////////////////////////////
//Muestra cadena de caracteres en coordenada [x,y]
void nokia_printstr(char* message)
{
for(; *message != '\0';message++){
nokia_printchar(*message);
}
}

And here how to use it:


Code:

nokia_init();
nokia_gotoxy(0,0);
texto="Hi! a txt line";
nokia_printstr(texto);
nokia_refresh();
delay_ms(1000);
nokia_clean_buffer();
nokia_gotoxy(0,0);
texto="a circle...";
nokia_circle(42,23,15,0,1);
nokia_refresh();

Soon, I'll be adding the possibility of showing bitmaps.

Display posts from previous: All Posts Oldest First Go

All times are GMT - 6 Hours


CCS Forum Index -> Code Library

Page 1 of 1

Jump to: Code Library Go

You cannot post new topics in this forum


You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group

You might also like