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 support@ccsinfo.com

LCD driver

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



Joined: 01 May 2004
Posts: 49

View user's profile Send private message

LCD driver
PostPosted: Sat May 15, 2004 12:07 pm     Reply with quote

I'm posting this here because I spent a long time looking for a driver that worked for me, I finally found this hidden in the back pages of the forum, it worked right off the bat for me. and was originally posted by a member named chava in this thread;
http://www.ccsinfo.com/forum/viewtopic.php?t=17323&highlight=picdem+2

Since I'm a beginner at this and had already spent a week trying to get my LCD to work, finding code that work for me very easily seemed like something others would find helpfull.

BTW, I'm using a PIC16F877A w/ a CrystalFontz LCD w/ aHD44780 compatible controller.


Code:
////////////////////   LCD   //////////////////////////////


// As defined in the following structure the pin connection is as follows:
//     A1  enable
//     A2  rw
//     A3  rs

//     D0  D4
//     D1  D5
//     D2  D6
//     D3  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.



//****************************************************************************************
#if defined(__PCH__)
   #byte lcd = 0xF83      // This puts the entire structure
#else
   #byte lcd = 8          // on to port D (at address 8)
#endif


//****************************************************************************************
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line

BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                            // These bytes need to be sent to the LCD
                            // to start it up.
                     // for 2 lines lcd: {0x0a,0xc,1,6}
                     // for 5x10 lcd:   {0x06,0xc,1,6}   
                     // for 5x7 lcd:      {0x20,0xc,1,6}

                             // The following are used for setting
                             // the I/O port direction register.


//***** lcd command port  *******************************************************************
struct lcd_command{
   char none:1;
   char enable:1;
   char read_write:1;//rw
   char data_command:1;//rs
   };
struct lcd_command lcd_command_port;
#locate lcd_command_port=5
//---------------------------------------------------
struct lcd_data{
   char data:4;
   };
struct lcd_data lcd_data_port;
#locate lcd_data_port=8

//************  "COMMAND / DATA definition  ************************************************************
#define COMMAND0 0
#define DATA1 1

//************  "READ / WRITE definition  ************************************************************
#define WRITE0 0   //LCD <- MPU
#define READ1 1  //LCD -> MPU

//************  "E_UP / E_DOWN definition  ************************************************************
#define E_DOWN 0
#define E_UP 1

//**********eeprom or flash******************************************************************************
#define EEPROM0 0   ;eeprom - not the program  memory
#define FLASH1 1   ;program memory

//*********  set tris d  *********************************************************************
#define set_tris_lcd_read(){\
   set_tris_a(TRISA & 0xf1/*0b11110001*/);\
   set_tris_d(TRISD | 0x0f/*0b00001111*/);\
   }
#define set_tris_lcd_write(){\
   set_tris_a(TRISA & 0xf1/*0b11110001*/);\
   set_tris_d(TRISD & 0xf0/*0b11110000*/);\
   }

//***********   clear LCD  ************************************
#define clear_lcd   lcd_send_byte(0x1,COMMAND0);//clear lcd display

//****************************************************************************************

//************************************************************
char lcd_read_byte(void){
      char low,high;
      set_tris_lcd_read();
      lcd_command_port.read_write = READ1;
      delay_cycles(1);
     
      lcd_command_port.enable = E_UP;
      delay_cycles(1);
      high = lcd_data_port.data & 0x0f;
      lcd_command_port.enable = E_DOWN;
      delay_cycles(1);
     
      lcd_command_port.enable = E_UP;
      delay_us(1);
      low = lcd_data_port.data & 0x0f;
      lcd_command_port.enable = E_DOWN;
      set_tris_lcd_write();
      return( (high << 4) | low);
}

//*************** -   - *********************************************
void lcd_write_nibble(char temp_wr){
//Purpose:
      lcd_data_port.data = temp_wr;
      delay_cycles(1);
      lcd_command_port.enable = 1;
      delay_us(2);
      lcd_command_port.enable = 0;
}
//*************** -   - *********************************************
void lcd_send_byte(char data , char data_or_command ) {

      lcd_command_port.data_command = COMMAND0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd_command_port.data_command = data_or_command;
      delay_cycles(1);
      lcd_command_port.read_write = WRITE0;
      delay_cycles(1);
      lcd_command_port.enable = E_DOWN;
      lcd_write_nibble(data >> 4);
      lcd_write_nibble(data & 0xf);
}
//************************************************************
void lcd_gotoxy( char location, char line) {//location 0...
   char address;

   if(line!=1)
     address=40;//was80
   else
     address=0;
   address+=location;
   lcd_send_byte(0x80|address,COMMAND0);
}
//********** -  1 - **************************************************
void lcd_init(void){
//Purpose: initiate the lcd
   //turnning PORTA0=analog, PORTA1-7=digital
   ADCON1=0x0e;
   
   //turnning command pin of lcd to output
   set_tris_lcd_write();

   //delay 15msec
   delay_ms(15);   
   lcd_command_port.enable=0;
   lcd_command_port.data_command=0;
   lcd_command_port.read_write=0;
   lcd_data_port.data=0;
   delay_ms(2);
   lcd_write_nibble(0x03);//was 30  ddram address: 1:1bit,line:1bit,address:4bit
   delay_ms(10);//more then 4.1msec

   lcd_write_nibble(0x03);//was 30
   delay_us(150);//more then 100usec

   lcd_write_nibble(0x03);//was 30
   delay_us(100);

   lcd_write_nibble(0x02);//was 20
   while(bit_test(lcd_read_byte(),7));

   lcd_send_byte(0x28,COMMAND0);//was 0x28 portd[3:0]=x2 then portd[3:0]=x8
                     //  4 bit low nibble, ddram address=0 first line

   lcd_send_byte(0x0c,COMMAND0);//disp on

   clear_lcd;

   lcd_send_byte(0x6,COMMAND0);//entry inc

   lcd_gotoxy(1,1);
   
   
   

}
//************************************************************
void lcd_putc( char c) {//this function works good
   switch (c) {
     case '\f'   : lcd_send_byte(1,COMMAND0);   delay_ms(2);   break;   //Clear display
     case '\n'   : lcd_gotoxy(1,2);                        break;   //Go to start of second line
     case '\b'   : lcd_send_byte(0x10,COMMAND0);               break;   //Move back one position
     default     : lcd_send_byte(c,DATA1);                  break;   //send the actual character
   }
}
//*************** -   - *********************************************
char lcd_getc( char location, char line) {
      char value;

    lcd_gotoxy(location,line);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd_command_port.data_command=1;
    value = lcd_read_byte();
    lcd_command_port.data_command=0;
    return(value);
      return 1;
}
//************************************************************
//*************************----***********************************
void lcd_put_string(char *string){
//put string, starting  from the curren cursor position
//assume that string not excides from lcd displayed RAM
   char index=0;

   while(string[index]!=0){
      lcd_putc(string[index++]);
   
   }
}


//************************************************************
void lcd_put_string_xy(char *string, char pos, char line){
//assume that string not excides from lcd displayed RAM
   lcd_gotoxy(pos,line);
   lcd_put_string(string);
}
//************************************************************
void stan_char(long *ptr,char line,char eeprom_or_flash){
//Purpose: write 16 chars, given in ptr location(eeprom or flash)
//to line of lcd, from the begining of the line
   char c,i;
   lcd_gotoxy(1,line);
/*OR:   switch(line==1) {
      case 1:lcd_send_byte(0x80,COMMAND);   //initiate lcd to write to line 1
      case 2:lcd_send_byte(0xc0,COMMAND);   //initiate lcd to write to line 2
   }*/
   for (i=0;i<16;i++){
      if (eeprom_or_flash)
         c=read_program_eeprom(ptr+1);
      else
         c=read_eeprom((char)ptr+1);
      lcd_putc(c);ptr++;
   }
}
/*
LCD_INIT
MOVLW DISP_ON ; Display On, Cursor On               = 0x0C
CALL SEND_CMD ; Send This command to the Display Module   
MOVLW CLR_DISP ; Clear the Display                  =0x01
CALL SEND_CMD ; Send This command to the Display Module
MOVLW ENTRY_INC ; Set Entry Mode Inc., No shift         =0x06
CALL SEND_CMD ; Send This command to the Display Module
*/



/*
SEND_CHAR
   MOVWF CHAR ; Character to be sent is in W
   CALL BUSY_CHECK ; Wait for LCD to be ready
   SWAPF CHAR, W
   ANDLW 0x0F ; Get upper nibble
   MOVWF LCD_DATA ; Send data to LCD
   BCF LCD_CNTL, RW ; Set LCD to read
   BSF LCD_CNTL, RS ; Set LCD to data mode
   BSF LCD_CNTL, E ; toggle E for LCD
   BCF LCD_CNTL, E
   MOVF CHAR, W
   ANDLW 0x0F ; Get lower nibble
   MOVWF LCD_DATA ; Send data to LCD
   BSF LCD_CNTL, E ; toggle E for LCD
   BCF LCD_CNTL, E*/

/*
SEND_CMD
   MOVWF CHAR ; Character to be sent is in W
   CALL BUSY_CHECK ; Wait for LCD to be ready
   MOVF CHAR,w
   ANDLW 0xF0 ; Get upper nibble
   MOVWF LCD_DATA ; Send data to LCD
   BCF LCD_CNTL,RW ; Set LCD to read
   BCF LCD_CNTL,RS ; Set LCD to command mode
   BSF LCD_CNTL,E ; toggle E for LCD
   BCF LCD_CNTL,E
   SWAPF CHAR,w
   ANDLW 0xF0 ; Get lower nibble
   MOVWF LCD_DATA ; Send data to LCD
   BSF LCD_CNTL,E ; toggle E for LCD
   BCF LCD_CNTL,E
*/

/*
BUSY_CHECK
   BSF STATUS, RP0 ; Select Register Bank1
   MOVLW 0xFF ; Set Port_D for input
   MOVWF LCD_DATA_TRIS
   BCF STATUS, RP0 ; Select Register Bank0
   BCF LCD_CNTL, RS ; Set LCD for Command mode
   BSF LCD_CNTL, RW ; Setup to read busy flag
   BSF LCD_CNTL, E ; Set E high
   BCF LCD_CNTL, E ; Set E low
   MOVF LCD_DATA, W ; Read upper nibble busy flag, DDRam address
   ANDLW 0xF0 ; Mask out lower nibble
   MOVWF TEMP
   BSF LCD_CNTL, E ; Toggle E to get lower nibble
   BCF LCD_CNTL, E
   SWAPF LCD_DATA, w ; Read lower nibble busy flag, DDRam address
   ANDLW 0x0F ; Mask out upper nibble
   IORWF TEMP ; Combine nibbles
   BTFSC TEMP, 7 ; Check busy flag, high = busy
   GOTO BUSY_CHECK ; If busy, check again
   BCF LCD_CNTL, RW
   BSF STATUS, RP0 ; Select Register Bank1
   MOVLW 0x0F
   MOVWF LCD_DATA_TRIS ; Set Port_D for output
   BCF STATUS, RP0 ; Select Register Bank0
*/
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