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

Driver for st7920 128x64 LCD
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
kaem1189



Joined: 27 Dec 2011
Posts: 12

View user's profile Send private message

Driver for st7920 128x64 LCD
PostPosted: Thu Nov 29, 2012 7:02 am     Reply with quote

st7920.h
Code:
/************************************************************************
*   LCD graphics driver for Digole 12864w with ST7920 driver using       *
*   CCS software. May work with other ST7920 driven LCD. It has          *
*   the following Pin assignments                                        *
*                                                                        *
*   Pin 1 ------------> Gnd                                              *   
*   Pin 2 ------------> +5volts                                          *
*   Pin 3 ------------> Contrast                                         *
*   Pin 4 ------------> Register Select                                  *
*   Pin 5 ------------> Read/Write                                       *
*   Pin 6 ------------> Enable                                           *
*   Pin 7-14 ---------> Data bits                                        *
*   Pin 15 -----------> PSB (parallel=high & serial=low)                 *
*   Pin 16 -----------> NoConnection                                     *
*   Pin 17 -----------> Reset                                            *
*   Pin 18 -----------> Vout                                             *
*   Pin 19 -----------> +5volts                                          *
*   Pin 20 -----------> Gnd                                              *
*                                                                        *
*   This driver is using 8bit parallel operation for optimal RAM         *
*   requirements, if you want i can change it to 4 bit operation.        *
*                                                                        *
*   Developed by Christian Rebogio                                       *
*   suggestions and request please email me at                           *
*   [email protected]                                          *
*                                                                        *
* READ THE DATASHEET FOR ST7920!!!!!!!                                   *
************************************************************************/
// change the pin assignment depending on your circuit

#define  rs  PIN_C0                    //COMMNAD/DATA SELECT
#define  rw  PIN_C1                    //READ/WRITE SELECT             
#define  e   PIN_C2                    //ENABLE SIGNAL                 
#define  rst PIN_C5                    //RESET SIGNAL   

#define ON   1
#define OFF   0
#define XVAL 16  // 16 X 16 or 256 for there is 8 word values for the upper and lower
#define YVAL 32

// PSB is tied to Vcc for this driver because this driver uses Parallel
// operation.
// data is sent using port B so change output_b() to other ports you
//want to use. Dont for get to change the Busy pin @ lcd_check_busy

#define GLCD_WIDTH   128



//////////////////////////////////////////////////////////////////////////////////
//The following are the functions included in this driver file
// glcd_readbyte();
// glcd_instruction( instruction );
// glcd_data( data ); - data can be an array of characters!
// glcd_check_busy();
// glcd_update(); -must be called always after writing a pixel or using functions
//                 from GRAPHICS.C .. Only applicaticable in Graphing mode
// glcd_fillscreen( ON or OFF);
// glcd_init_graph(); initialize for graphing mode
// glcd_init_basic(); initilize for accessing the stored Characters
//                     you can use glcd_data() for writing text
// glcd_pixel(x coordinate, y coordinate, ON or OFF); 
//            -WORKS WITH GRAPHIC.C  from CCS Drivers
// glcd_plot_image(width,height,X coor, Y coor, inverse);
//            -plots the image[] array. Declare it first before this driver.
//             or modify this driver
//
//////////////////////////////////////////////////////////////////////////////////



typedef union
{
  int16 word;
  int8 nbyte[2];
} Dots;

typedef struct
{
  int1 refresh;
  Dots pix[YVAL][XVAL];   // Max dimensions for display (x,y) = (128,32)
  } GD_RAM;             //  (0,0) corresponds to upper lefthand corner.

GD_RAM gdram;


unsigned int8 glcd_readByte (unsigned int1 address)
{
  unsigned int8 data;   // Stores the data read from the LCD
  if(address==1){
     output_high(rs);
  }
  if(address==0){
     output_low(rs);
  }
  output_high(rw);//GLCD_RW = RW_READ;      // Set for reading
  output_high(e);//GLCD_E = 1;      // Pulse the enable pin
  delay_us(1);
  data=input_b();      // Get the data from the display's output register
  output_low(e);//GLCD_E = 0;
  return (data);
}

 
void glcd_check_busy(){
   int1 busy=1;
   output_low(rs);      // LOW RS and High RW will put the lcd to
   output_high(rw);      // read busy flag and address counter
   while(busy){         // will cycle until busy flag is 0
      output_high(e);
      if(!input(PIN_B7)){
         busy=0;
      }
      output_low(e);
   }
}
 
void glcd_instruction(unsigned char x){
   glcd_check_busy();      //must be satisfied before sending instruction
   output_low(rs);      // LOW RS and LOW RW will put the lcd to
   output_low(rw);      // Write instruction mode
   output_b(x);         // 8bit data to bus
   output_high(e);      // enable
   delay_us(1);       
   output_low(e);      // disable
}
void glcd_data(unsigned char x){
   glcd_check_busy();
   output_high(rs);      // HIGH RS and LOW RW will put the lcd to
   output_low(rw);      // Write data register mode
   output_b(x);
   output_high(e);
   delay_us(1);
   output_low(e);
}
 

void glcd_fillScreen (unsigned int1 color)
{
  int8 v, h;
  int16 d;


  d = (color == ON ? 0xFFFFL : 0x0000L);

  for (v=0; v < YVAL; v++)
  {
    for (h=0; h < XVAL; h++)
    {
      gdram.pix[v][h].word = d;
    }
  }
  gdram.refresh = TRUE;
}


void glcd_update ()
{
  int8 v, h;


  if (gdram.refresh)
  {
    for (v=0; v <YVAL; v++)
    {
      glcd_instruction( 0x80 | v);   // Set Vertical Address.
      glcd_instruction( 0x80 | 0);   // Set Horizontal Address.

      for (h=0; h <XVAL; h++)
      {
        glcd_data( gdram.pix[v][h].nbyte[1]);   // Write High Byte.
        glcd_data(  gdram.pix[v][h].nbyte[0]);   // Write Low Byte.
      }
    }
    gdram.refresh = FALSE;
  }
}

void glcd_init_graph(){
   delay_ms(40);
   output_low(rst);         //reset LCD
   delay_us(1);                     
   output_high(rst);        //LCD normal operation
   glcd_instruction(0x30);   //set 8 bit operation and basic instruction set
   delay_us(144);
   glcd_instruction(0x0C);   //display on cursor off and char blink off
   delay_us(100);
   glcd_instruction(0x01);   //display clear
   delay_ms(10);
   glcd_instruction(0x06);   //entry mode set
   delay_us(72);                 
  glcd_instruction(0x34);    // Select extended instruction set.
  delay_ms (10);
  glcd_instruction(0x36);    // Graphic display ON.
  delay_ms (10);

  glcd_fillScreen (OFF);
  glcd_update ();

}

void glcd_init_basic(){
   delay_ms(40);
   output_low(rst);         //reset LCD
   delay_us(1);                     
   output_high(rst);        //LCD normal operation
   glcd_instruction(0x30);   //set 8 bit operation and basic instruction set
   delay_us(144);
   glcd_instruction(0x0C);   //display on cursor off and char blink off
   delay_us(100);
   glcd_instruction(0x01);   //display clear
   delay_ms(10);
   glcd_instruction(0x06);   //entry mode set
   delay_us(72);                 
}

void glcd_pixel(int8 x, int8 y, int1 color)
{
  int8 v, h, b;
  if(y>31){x += 128; y-= 32;};
  v = y;
  h = x/16;
  b = 15 - (x%16);
 
  if (color == ON) bit_set (gdram.pix[v][h].word, b);
  else bit_clear (gdram.pix[v][h].word, b);

  gdram.refresh = TRUE;
}

void glcd_plot_image(int width,int height,int x,int y,int inverse)
{
   unsigned int i=0, j=0, k=0;
   unsigned int16 count=0;
   //glcd_fillScreen(OFF);                        //Clears the screen (opt.)
   for(j=0;j<height;j++)
      {   
         for(;i<width;)
         {
            for(k=8;k>0;k--){
               if(inverse)glcd_pixel(i+x,j+y,~bit_test(image[count],(k-1)));
               else glcd_pixel(i+x,j+y,bit_test(image[count],(k-1)));
               
               i++;
            }
            count++;
         }
      i=0;
      }
}
//credits to http://www.ccsinfo.com/forum/viewtopic.php?t=32819&highlight=st7920//
///////////////////////////////////////////////////////////////////////////////////



Sample Code

Code:

#include <18F4550.h>
#device adc=8;
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,PUT,CPUDIV1,PLL1
#use delay(internal=8M)
#use RS232(baud=9600,UART1)

const int8 image[]={
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x3b, 0xb0, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x03, 0xf7, 0x6b, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x07, 0xbd, 0xb1, 0x40, 0x00, 0x00,
    0x00, 0x00, 0x0f, 0xf7, 0xdd, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x1f, 0xff, 0x6a, 0xb0, 0x00, 0x00,
    0x00, 0x00, 0x1e, 0xff, 0xdb, 0x68, 0x00, 0x00,
    0x00, 0x00, 0x3f, 0xdd, 0xfe, 0xf0, 0x00, 0x00,
    0x00, 0x00, 0x37, 0xff, 0xb7, 0xa8, 0x00, 0x00,
    0x00, 0x00, 0x3e, 0xd5, 0x5a, 0xfc, 0x00, 0x00,
    0x00, 0x00, 0x7f, 0x6a, 0x4b, 0x74, 0x00, 0x00,
    0x00, 0x00, 0x36, 0x91, 0x29, 0x7c, 0x00, 0x00,
    0x00, 0x00, 0x3e, 0x44, 0x95, 0x5a, 0x00, 0x00,
    0x00, 0x00, 0x3d, 0x11, 0x24, 0xfc, 0x00, 0x00,
    0x00, 0x00, 0x3e, 0xa4, 0x4a, 0xb8, 0x00, 0x00,
    0x00, 0x00, 0x36, 0x91, 0x25, 0x5c, 0x00, 0x00,
    0x00, 0x00, 0x3e, 0xbc, 0x9f, 0xb8, 0x00, 0x00,
    0x00, 0x00, 0x1d, 0x46, 0x51, 0x58, 0x00, 0x00,
    0x00, 0x00, 0x0d, 0x79, 0x2e, 0xb4, 0x00, 0x00,
    0x00, 0x00, 0x26, 0x54, 0x95, 0x90, 0x00, 0x00,
    0x00, 0x00, 0x0a, 0x0a, 0x52, 0xb4, 0x00, 0x00,
    0x00, 0x00, 0x12, 0xa0, 0xa4, 0x94, 0x00, 0x00,
    0x00, 0x00, 0x0a, 0x4a, 0x2a, 0xa8, 0x00, 0x00,
    0x00, 0x00, 0x05, 0x01, 0x51, 0x50, 0x00, 0x00,
    0x00, 0x00, 0x05, 0x54, 0x2a, 0x20, 0x00, 0x00,
    0x00, 0x00, 0x02, 0x09, 0x55, 0x50, 0x00, 0x00,
    0x00, 0x00, 0x01, 0xa2, 0xa9, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x01, 0x10, 0x2a, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x01, 0xab, 0xac, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x01, 0x44, 0x15, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x01, 0x92, 0xaa, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x24, 0xaa, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x28, 0x94, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x22, 0x4a, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x14, 0x2a, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x4a, 0xaa, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x21, 0x55, 0x40, 0x00, 0x00,
    0x00, 0x00, 0x02, 0x09, 0x55, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x02, 0x10, 0x52, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x0e, 0x05, 0x0a, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x1f, 0x00, 0x54, 0x0d, 0x00, 0x00,
    0x00, 0x00, 0x56, 0x01, 0x24, 0x0d, 0x50, 0x00,
    0x00, 0x02, 0xff, 0x00, 0x48, 0x06, 0xd4, 0x00,
    0x00, 0x0d, 0xb5, 0x00, 0x10, 0x0b, 0x6b, 0xa0,
    0x00, 0x77, 0xff, 0x80, 0x00, 0x06, 0xbd, 0x50,
    0x03, 0x5b, 0x57, 0x00, 0x7c, 0x87, 0xee, 0xfc,
    0x1d, 0xef, 0xfd, 0x80, 0x9e, 0x06, 0xb7, 0xaf
};



#include "st7920.h"
#include "GRAPHICS.C"

void main(){
glcd_init_graph();
   while(1){
     
      glcd_fillscreen(ON);
      glcd_update();
      delay_ms(1000);
     
      glcd_fillscreen(OFF);
      glcd_update();
      delay_ms(1000);
     
      glcd_plot_image(60,50,0,0,0);
      glcd_update();
      delay_ms(1000);
   }
}


Waiting for your feedback Guys.. thank you


Last edited by kaem1189 on Tue Aug 13, 2013 6:52 am; edited 1 time in total
Mr.Bricker



Joined: 05 Dec 2012
Posts: 1

View user's profile Send private message

PostPosted: Wed Dec 05, 2012 3:42 pm     Reply with quote

I was lost my hope to find this driver. Thank you so much.. Can you give us an example program to use this driver?

I tried my test program but have too many compile error.


Code:
#include <18F4550.h>
#include <st7920.c>
#include <GRAPHICS.C>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CPUDIV4                  //System Clock by 4
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST   
#USE DELAY(INTERNAL=8000000)
main(){
delay_ms(1000);

while(glcd_check_busy())
delay_ms(10);
while(1){
glcd_fillscreen(ON);
delay_ms(500);
glcd_fillscreen(OFF);
delay_ms(500);
}
}


So not tried yet. Sad [/code]
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Thu Dec 06, 2012 7:29 am     Reply with quote

You are doing a lot of things out of order in your main. For example, you include his driver which uses delay() calls, but you don't specify your #use delay() till after. Similar issues with the fuses.

Always, ALWAYS, put your FUSES and device specific preprocessor directives before any code and includes except for the include for your specific chip, which must come first.
kaem1189



Joined: 27 Dec 2011
Posts: 12

View user's profile Send private message

sample
PostPosted: Sat Dec 08, 2012 9:28 am     Reply with quote

Code:
#include <18F2550.h>
#device adc=8;
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,CPUDIV1,PUT
#use delay(clock=20M)
#include <st7920.h>

const unsigned char TAB[]={'A','B','C','D','E','F','g','h'};
int i ;
void main ()
{
glcd_init_basic();
while(1)
{
   for(i=0;i<8;i++)
   {
      glcd_data(TAB[i]);
      delay_ms(1000);
   }
   while(1);

}
}
kaem1189



Joined: 27 Dec 2011
Posts: 12

View user's profile Send private message

PostPosted: Sat Dec 08, 2012 9:37 am     Reply with quote

Mr.Bricker wrote:
I was lost my hope to find this driver. Thank you so much.. Can you give us an example program to use this driver?

I tried my test program but have too many compile error.


Code:
#include <18F4550.h>
#include <st7920.c>
#include <GRAPHICS.C>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CPUDIV4                  //System Clock by 4
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST   
#USE DELAY(INTERNAL=8000000)
main(){
delay_ms(1000);

while(glcd_check_busy())
delay_ms(10);
while(1){
glcd_fillscreen(ON);
delay_ms(500);
glcd_fillscreen(OFF);
delay_ms(500);
}
}


So not tried yet. Sad [/code]


Try this. Maybe it will work:
Code:

#include <18F4550.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CPUDIV1                  //System Clock by 4
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST   
#USE DELAY(INTERNAL=8000000)

#include <st7920.c>
#include <GRAPHICS.C>

main(){
glcd_init_graph();
while(1){
glcd_fillscreen(ON);
delay_ms(500);
glcd_fillscreen(OFF);
delay_ms(500);
}
}
tomat5



Joined: 01 Jan 2013
Posts: 1

View user's profile Send private message

Re: Driver for st7920 128x64 LCD
PostPosted: Wed Jan 02, 2013 1:54 pm     Reply with quote

kaem1189 wrote:
st7920.h
Code:
/************************************************************************
*   LCD graphics driver for Digole 12864w with ST7920 driver using       *
*   CCS software. May work with other ST7920 driven LCD. It has          *
*   the following Pin assignments                                        *
*                                                                        *




Thanks very much, it's working great. This is a big help for me. thanks again.
kaem1189



Joined: 27 Dec 2011
Posts: 12

View user's profile Send private message

PostPosted: Thu Jan 03, 2013 1:47 am     Reply with quote

GREAT!!! welcome!
kristian



Joined: 16 Mar 2013
Posts: 3

View user's profile Send private message

PostPosted: Sat Mar 16, 2013 5:35 pm     Reply with quote

HI.
I'm using MikroC software to write codes. Can you explain me what i have to write in order to make MikroC know where I have linked DB0 -DB7 pins, Register Select pin, etc...
For example:
sbit RS at RB0_bit
sbit D0 at RB1_bit

Thank you.
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Sat Mar 16, 2013 6:16 pm     Reply with quote

This is not a MicroC forum. Won't find much help with it here.
kristian



Joined: 16 Mar 2013
Posts: 3

View user's profile Send private message

PostPosted: Sun Mar 17, 2013 4:48 am     Reply with quote

jeremiah wrote:
This is not a MicroC forum. Won't find much help with it here.

So i can't use this library with MikroC?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Sun Mar 17, 2013 6:37 am     Reply with quote

You'll have to port it to MicroC, but this forum doesn't cover MicroC. You'll need to ask the MicroC forums for info on how to port it as most of us don't use MicroC
kristian



Joined: 16 Mar 2013
Posts: 3

View user's profile Send private message

PostPosted: Sun Mar 17, 2013 6:55 am     Reply with quote

Ok, thank you
kaem1189



Joined: 27 Dec 2011
Posts: 12

View user's profile Send private message

PostPosted: Fri May 24, 2013 8:19 pm     Reply with quote

Im glad i could help everyone. Smile
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Wed Jun 05, 2013 8:30 am     Reply with quote

Hi kaem1189

I am trying to implement a serial driver for a glcd (st7920 controller) using as an example the one that you posted here.
Basic mode seems to work ok, I can show text without problem.
But when trying to use the graphic mode I have a strange behaviour... sometimes it works ok but other times there is a kind of "noise" in the screen, I mean, some random pixels are on or strange patterns appears.
First I though that it was a timing problem but after changing them (increasing and decreasing them) the problem persist.
Do you ever experienced this kind of behaviour?

I'm stuck with this because after analyzing several times the routines, they seems to be ok in particular when sometimes it works fine...

Are there any requirements about filtering the power supply to the GLCD? perhaps what it is happening is just electrical noise...

Any idea? Confused
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Tue Jun 11, 2013 8:09 am     Reply with quote

In the display there is a pin marked as NC, and if I touch it, a lot of "noise" appears on the screen. I tied it to ground by a 22k resistor and all the problems disappeared...
Very strange... Shocked

So it was a "hardware" problem and not a software one.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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