| lazuribicci 
 
 
 Joined: 06 Feb 2010
 Posts: 10
 
 
 
			    
 
 | 
			
				| Nokia 1100 lcd driver with graphics functions, big font size |  
				|  Posted: Thu May 05, 2011 6:46 am |   |  
				| 
 |  
				| This driver is for nokia lcd with PCF8814 controller for example 1100, 1110i... etc. 
 As you can see on picture, you can plot a line, circle, rectangle
 and fill in these graphics.
 you can also use different font size
 
 one of the advantages of the driver is very similar with 128*64 GLCD with HDM64GS12 controller
 
 besides, the disadvantage of this, the driver file uses a lot of ram about 775 bytes
 enjoy it
   
 Best Regards,
 
 Fatih GENC
 
 
   
 
  	  | Code: |  	  | ////////////////////// ///    lcd1100.c
 ///
 ///    by Fatih GENC
 ///    fatihgenc81@hotmail.com
 ///    5/5/2011
 //////////////////////
 
 #define sclk   PIN_B4
 #define sda    PIN_B5
 #define cs     PIN_B6
 #define rst    PIN_B7
 
 #define CMD      0
 #define DATA   1
 
 #define lcd_WIDTH   96
 
 #ifndef ON
 #define ON           1
 #endif
 
 #ifndef OFF
 #define OFF          0
 #endif
 
 void Lcd_Clear(void);
 void Lcd_Init(void);
 void Lcd_Write(int1 cd,unsigned char c);
 void Gotoxy(char x,char y);
 void lcd_pixel(unsigned char x,unsigned char y, int1 color);
 void lcd_line(int8 x1, int8 y1, int8 x2, int8 y2, int1 color);
 void lcd_circle(int8 x, int8 y, int8 radius, int1 fill, int1 color);
 void lcd_text57(int8 x, int8 y, char* textptr, int8 size, int1 color);
 void lcd_rect(int8 x1, int8 y1, int8 x2, int8 y2, int1 fill, int1 color);
 
 
 static int8 memory[96][8]; //LCD memory data
 static int8 XX,YY;
 
 
 // lookup table, here you can modify the font
 const int8 FONT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
 0x00, 0x00, 0x5F, 0x00, 0x00, // !
 0x00, 0x03, 0x00, 0x03, 0x00, // "
 0x14, 0x3E, 0x14, 0x3E, 0x14, // #
 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
 0x43, 0x33, 0x08, 0x66, 0x61, // %
 0x36, 0x49, 0x55, 0x22, 0x50, // &
 0x00, 0x05, 0x03, 0x00, 0x00, // '
 0x00, 0x1C, 0x22, 0x41, 0x00, // (
 0x00, 0x41, 0x22, 0x1C, 0x00, // )
 0x14, 0x08, 0x3E, 0x08, 0x14, // *
 0x08, 0x08, 0x3E, 0x08, 0x08, // +
 0x00, 0x50, 0x30, 0x00, 0x00, // ,
 0x08, 0x08, 0x08, 0x08, 0x08, // -
 0x00, 0x60, 0x60, 0x00, 0x00, // .
 0x20, 0x10, 0x08, 0x04, 0x02, // /
 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
 0x00, 0x04, 0x02, 0x7F, 0x00, // 1
 0x42, 0x61, 0x51, 0x49, 0x46, // 2
 0x22, 0x41, 0x49, 0x49, 0x36, // 3
 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
 0x27, 0x45, 0x45, 0x45, 0x39, // 5
 0x3E, 0x49, 0x49, 0x49, 0x32, // 6
 0x01, 0x01, 0x71, 0x09, 0x07, // 7
 0x36, 0x49, 0x49, 0x49, 0x36, // 8
 0x26, 0x49, 0x49, 0x49, 0x3E, // 9
 0x00, 0x36, 0x36, 0x00, 0x00, // :
 0x00, 0x56, 0x36, 0x00, 0x00, // ;
 0x08, 0x14, 0x22, 0x41, 0x00, // <
 0x14, 0x14, 0x14, 0x14, 0x14, // =
 0x00, 0x41, 0x22, 0x14, 0x08, // >
 0x02, 0x01, 0x51, 0x09, 0x06, // ?
 0x3E, 0x41, 0x59, 0x55, 0x5E, // @
 0x7E, 0x09, 0x09, 0x09, 0x7E, // A
 0x7F, 0x49, 0x49, 0x49, 0x36, // B
 0x3E, 0x41, 0x41, 0x41, 0x22, // C
 0x7F, 0x41, 0x41, 0x41, 0x3E, // D
 0x7F, 0x49, 0x49, 0x49, 0x41, // E
 0x7F, 0x09, 0x09, 0x09, 0x01, // F
 0x3E, 0x41, 0x41, 0x49, 0x3A, // G
 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
 0x00, 0x41, 0x7F, 0x41, 0x00, // I
 0x30, 0x40, 0x40, 0x40, 0x3F, // J
 0x7F, 0x08, 0x14, 0x22, 0x41, // K
 0x7F, 0x40, 0x40, 0x40, 0x40, // L
 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
 0x7F, 0x02, 0x04, 0x08, 0x7F, // N
 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
 0x7F, 0x09, 0x09, 0x09, 0x06, // P
 0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
 0x7F, 0x09, 0x09, 0x09, 0x76};// R
 
 const int8 FONT2[44][5]={0x26, 0x49, 0x49, 0x49, 0x32, // S
 0x01, 0x01, 0x7F, 0x01, 0x01, // T
 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
 0x7F, 0x20, 0x10, 0x20, 0x7F, // W
 0x41, 0x22, 0x1C, 0x22, 0x41, // X
 0x07, 0x08, 0x70, 0x08, 0x07, // Y
 0x61, 0x51, 0x49, 0x45, 0x43, // Z
 0x00, 0x7F, 0x41, 0x00, 0x00, // [
 0x02, 0x04, 0x08, 0x10, 0x20, // \
 0x00, 0x00, 0x41, 0x7F, 0x00, // ]
 0x00, 0x07, 0x05, 0x07, 0x00, // ° (degree)
 0x40, 0x40, 0x40, 0x40, 0x40, // _
 0x00, 0x01, 0x02, 0x04, 0x00, // `
 0x20, 0x54, 0x54, 0x54, 0x78, // a
 0x7F, 0x44, 0x44, 0x44, 0x38, // b
 0x38, 0x44, 0x44, 0x44, 0x44, // c
 0x38, 0x44, 0x44, 0x44, 0x7F, // d
 0x38, 0x54, 0x54, 0x54, 0x18, // e
 0x04, 0x04, 0x7E, 0x05, 0x05, // f
 0x08, 0x54, 0x54, 0x54, 0x3C, // g
 0x7F, 0x08, 0x04, 0x04, 0x78, // h
 0x00, 0x44, 0x7D, 0x40, 0x00, // i
 0x20, 0x40, 0x44, 0x3D, 0x00, // j
 0x7F, 0x10, 0x28, 0x44, 0x00, // k
 0x00, 0x41, 0x7F, 0x40, 0x00, // l
 0x7C, 0x04, 0x78, 0x04, 0x78, // m
 0x7C, 0x08, 0x04, 0x04, 0x78, // n
 0x38, 0x44, 0x44, 0x44, 0x38, // o
 0x7C, 0x14, 0x14, 0x14, 0x08, // p
 0x08, 0x14, 0x14, 0x14, 0x7C, // q
 0x00, 0x7C, 0x08, 0x04, 0x04, // r
 0x48, 0x54, 0x54, 0x54, 0x20, // s
 0x04, 0x04, 0x3F, 0x44, 0x44, // t
 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
 0x44, 0x28, 0x10, 0x28, 0x44, // x
 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
 0x44, 0x64, 0x54, 0x4C, 0x44, // z
 0x00, 0x08, 0x36, 0x41, 0x41, // {
 0x00, 0x00, 0x7F, 0x00, 0x00, // |
 0x41, 0x41, 0x36, 0x08, 0x00, // }
 0x02, 0x01, 0x02, 0x04, 0x02};// ~
 /////////////////////////////////////////////////////////////////////////
 
 
 // clear LCD
 void Lcd_Clear(void){
 unsigned int i;
 Lcd_Write(CMD,0x40); // Y = 0
 Lcd_Write(CMD,0xb0);
 Lcd_Write(CMD,0x10); // X = 0
 Lcd_Write(CMD,0x0);
 Lcd_Write(CMD,0xae); // disable display;
 for(i=0;i<255;i++)
 Lcd_Write(DATA,0x00);
 for(i=0;i<255;i++)
 Lcd_Write(DATA,0x00);
 for(i=0;i<255;i++)
 Lcd_Write(DATA,0x00);
 for(i=0;i<99;i++)
 Lcd_Write(DATA,0x00);
 Lcd_Write(CMD,0xaf); // enable display;
 }
 
 // Purpose:       Initialize the LCD.
 //                Call before using any other LCD function.
 void Lcd_Init(void){
 output_low(cs);
 output_low(rst);
 delay_ms(5);         // 5mS so says the stop watch(less than 5ms will not work)
 output_high(rst);
 Lcd_Write(CMD,0x20); // write VOP register
 Lcd_Write(CMD,0x90);
 Lcd_Write(CMD,0xA4); // all on/normal display
 Lcd_Write(CMD,0x2F); // Power control set(charge pump on/off)
 Lcd_Write(CMD,0x40); // set start row address = 0
 Lcd_Write(CMD,0xb0); // set Y-address = 0
 Lcd_Write(CMD,0x10); // set X-address, upper 3 bits
 Lcd_Write(CMD,0x0);  // set X-address, lower 4 bits
 Lcd_Write(CMD,0xC8); // mirror Y axis (about X axis)
 Lcd_Write(CMD,0xa1); // Invert screen in horizontal axis
 Lcd_Write(CMD,0xac); // set initial row (R0) of the display
 Lcd_Write(CMD,0x07);
 //Lcd_Write(CMD,0xF9); //
 Lcd_Write(CMD,0xaf); // display ON/OFF
 
 Lcd_Clear(); // clear LCD
 Lcd_Write(CMD,0xa7); // invert display
 delay_ms(100);
 Lcd_Write(CMD,0xa6); // normal display (non inverted)
 delay_ms(100);
 }
 
 // Purpose:    Write a byte of data to lcd
 // Inputs:     c - the byte of data to write
 void Lcd_Write(int1 cd,unsigned char c){
 int i;
 output_low(cs);
 output_low(sclk);
 output_bit(sda,cd);
 output_high(sclk);
 
 if(cd==DATA)
 {
 memory[XX][YY]= c; //write data to memory
 XX++;
 }
 
 for(i=0;i<8;i++){
 output_low(sclk);
 if((c & 0x80))
 output_high(sda);
 else
 output_low(sda);
 output_high(sclk);
 c <<= 1;
 delay_us(10);
 }
 output_high(cs);
 
 
 }
 
 void Gotoxy(char x,char y){
 Lcd_Write(CMD,(0xB0|(y&0x0F)));       // Y axis initialisation: 0100 yyyy
 Lcd_Write(CMD,(0x00|(x&0x0F)));       // X axis initialisation: 0000 xxxx ( x3 x2 x1 x0)
 Lcd_Write(CMD,(0x10|((x>>4)&0x07))); // X axis initialisation: 0010 0xxx  ( x6 x5 x4)
 
 }
 
 // Purpose:    Turn a pixel on a graphic LCD on or off
 // Inputs:     1) x - the x coordinate of the pixel
 //             2) y - the y coordinate of the pixel
 //             3) color - ON or OFF
 void lcd_pixel(unsigned char x,unsigned char y, int1 color){
 char aux[8];
 char i,o;
 char c=1;
 char index;
 int8 temp;
 
 XX=x;
 YY=y/8;
 
 Gotoxy(x,YY);
 temp=memory[x][YY];
 
 if(color == ON)
 bit_set(temp, y%8);        // Turn the pixel on
 else                          // or
 bit_clear(temp, y%8);      // turn the pixel off
 
 Lcd_Write(DATA,temp);
 }
 
 /////////////////////////////////////////////////////////////////////////
 // Purpose:       Draw a line on a nokia 1100 LCD
 //                line drawing algorithm
 // Inputs:        (x1, y1) - the start coordinate
 //                (x2, y2) - the end coordinate
 //                color - ON or OFF
 // Dependencies:  glcd_pixel()
 /////////////////////////////////////////////////////////////////////////
 void lcd_line(int8 x1, int8 y1, int8 x2, int8 y2, int1 color)
 {
 int16        dy, dx;
 signed int8  addx=1, addy=1;
 signed int16 P, diff;
 
 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)
 {
 lcd_pixel(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)
 {
 lcd_pixel(x1, y1, color);
 
 if(P < 0)
 {
 P  += dx;
 y1 += addy;
 }
 else
 {
 P  += diff;
 x1 += addx;
 y1 += addy;
 }
 }
 }
 }
 
 /////////////////////////////////////////////////////////////////////////
 // Purpose:       Draw a circle on a nokia 1100 LCD
 // Inputs:        (x,y) - the center of the circle
 //                radius - the radius of the circle
 //                fill - YES or NO
 //                color - ON or OFF
 /////////////////////////////////////////////////////////////////////////
 void lcd_circle(int8 x, int8 y, int8 radius, int1 fill, int1 color)
 {
 signed int8  a, b, P;
 
 a = 0;
 b = radius;
 P = 1 - radius;
 
 do
 {
 if(fill)
 {
 lcd_line(x-a, y+b, x+a, y+b, color);
 lcd_line(x-a, y-b, x+a, y-b, color);
 lcd_line(x-b, y+a, x+b, y+a, color);
 lcd_line(x-b, y-a, x+b, y-a, color);
 }
 else
 {
 lcd_pixel(a+x, b+y, color);
 lcd_pixel(b+x, a+y, color);
 lcd_pixel(x-a, b+y, color);
 lcd_pixel(x-b, a+y, color);
 lcd_pixel(b+x, y-a, color);
 lcd_pixel(a+x, y-b, color);
 lcd_pixel(x-a, y-b, color);
 lcd_pixel(x-b, y-a, color);
 }
 
 if(P < 0)
 P += 3 + 2 * a++;
 else
 P += 5 + 2 * (a++ - b--);
 } while(a <= b);
 }
 
 /////////////////////////////////////////////////////////////////////////
 // Purpose:       Write text on a nokia 1100 LCD
 // Inputs:        (x,y) - The upper left coordinate of the first letter
 //                textptr - A pointer to an array of text to display
 //                size - The size of the text: 1 = 5x7, 2 = 10x14, ...
 //                color - ON or OFF
 /////////////////////////////////////////////////////////////////////////
 void lcd_text57(int8 x, int8 y, char* textptr, int8 size, int1 color)
 {
 int8 j, k, l, m;                       // Loop counters
 int8 pixelData[5];                     // Stores character data
 
 for(; *textptr != '\0'; ++textptr, ++x)// Loop through the passed string
 {
 if(*textptr < 'S') // Checks if the letter is in the first font array
 memcpy(pixelData, FONT[*textptr - ' '], 5);
 else if(*textptr <= '~') // Check if the letter is in the second font array
 memcpy(pixelData, FONT2[*textptr - 'S'], 5);
 else
 memcpy(pixelData, FONT[0], 5);   // Default to space
 
 // Handles newline and carriage returns
 switch(*textptr)
 {
 case '\n':
 y += 7*size + 1;
 continue;
 case '\r':
 x = 0;
 continue;
 }
 
 if(x+5*size >= lcd_WIDTH)          // Performs character wrapping
 {
 x = 0;                           // Set x at far left position
 y += 7*size + 1;                 // Set y at next position down
 }
 for(j=0; j<5; ++j, x+=size)         // Loop through character byte data
 {
 for(k=0; k < 7; ++k)             // Loop through the vertical pixels
 {
 if(bit_test(pixelData[j], k)) // Check if the pixel should be set
 {
 for(l=0; l < size; ++l)    // These two loops change the
 {                          // character's size
 for(m=0; m < size; ++m)
 {
 lcd_pixel(x+m, y+k*size+l, color); // Draws the pixel
 }
 }
 }
 }
 }
 }
 }
 
 /////////////////////////////////////////////////////////////////////////
 // Purpose:       Draw a rectangle on a nokia 1100 LCD
 // Inputs:        (x1, y1) - the start coordinate
 //                (x2, y2) - the end coordinate
 //                fill  - YES or NO
 //                color - ON or OFF
 // Dependencies:  glcd_pixel(), glcd_line()
 /////////////////////////////////////////////////////////////////////////
 void lcd_rect(int8 x1, int8 y1, int8 x2, int8 y2, int1 fill, int1 color)
 {
 if(fill)
 {
 
 int8  i, xmin, xmax, ymin, ymax;
 
 if(x1 < x2)                            //  Find x min and max
 {
 xmin = x1;
 xmax = x2;
 }
 else
 {
 xmin = x2;
 xmax = x1;
 }
 
 if(y1 < y2)                            // Find the y min and max
 {
 ymin = y1;
 ymax = y2;
 }
 else
 {
 ymin = y2;
 ymax = y1;
 }
 
 for(; xmin <= xmax; ++xmin)
 {
 for(i=ymin; i<=ymax; ++i)
 {
 lcd_pixel(xmin, i, color);
 }
 }
 }
 else
 {
 lcd_line(x1, y1, x2, y1, color);      // Draw the 4 sides
 lcd_line(x1, y2, x2, y2, color);
 lcd_line(x1, y1, x1, y2, color);
 lcd_line(x2, y1, x2, y2, color);
 }
 }
 
 | 
 
 test file
 
 
  	  | Code: |  	  | 
 //test.c
 
 #include <18f2620.h>
 #fuses H4,NOWDT,NOLVP,NOPROTECT
 #use delay(clock=40000000)
 
 #include "lcd1100.c"
 
 int8 i;
 char c[]="TEST";
 
 void main (void) {
 
 
 Lcd_Init();
 
 lcd_circle(76, 38, 10, 0, 1);
 
 lcd_line(95, 0, 0, 64, 1);
 
 lcd_text57(10, 15, c, 1, 1);
 
 lcd_text57(10, 25, c, 2, 1);
 
 lcd_rect(60, 50, 92, 60, 1, 1);
 
 lcd_text57(65, 52, c, 1, 0);
 
 while(1);
 }
 | 
 |  |