pmaggi
 
 
  Joined: 05 Jun 2013 Posts: 10
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Nokia 5110 driver | 
			 
			
				 Posted: Sat Aug 22, 2015 4:32 pm     | 
				     | 
			 
			
				
  | 
			 
			
				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. | 
			 
		  |