CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Nokia 5110 driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

Nokia 5110 driver
PostPosted: Sat Aug 22, 2015 4:32 pm     Reply with quote

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:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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