[SOLVED] PIC18F4550 LCD Interfacing.

Status
Not open for further replies.

Praveen Kumar P S

Member level 4
Joined
Aug 21, 2014
Messages
79
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Location
India
Visit site
Activity points
627
Hello Guys.....

I was trying to interface a 16x2 lcd with a pic18f4550. There is no problem with my lcd connection...

Here my code...

Code:
#include <18F4550.h> 
#fuses XT, NOWDT, PUT, BROWNOUT, CPUDIV1 
#use delay(clock=48000000)
#include<flex_lcd216.c>

void main() 
{    
    delay_ms(500); 
    lcd_init(); 
    delay_ms(500); 
    for(;;) 
     { 
    lcd_gotoxy(1,1); 
    delay_ms(100); 
    lcd_putc("HI SWEETY "); 
    delay_ms(1000); 
    lcd_gotoxy(2,2); 
    delay_ms(100); 
    printf(lcd_putc,"HELLO SWEETY"); 
    delay_ms(1000); 
    output_high(PIN_B0); 
    delay_ms(100); 
    output_low(PIN_B0); 
    delay_ms(100); 
  } 
    
}



It compile without error..but when run on a real hardware the lcd displays everything in a improper way with unreadable characters..
It shows something like "SWEHI **8*??/HESW***" ( *----->Characters not in my keyboard )
I think This is due to the clock delay i m using( also my board consist of a inbuilt 16Mhz Crystal)

i m using a flex_lcd driver .....

ACTUALLY I dont know how to set the clock correctly....Plz help me guys....

Thank YOU.............
 

Are u using PICDEM2+ board. Check the connection of LCD to MCU, a 16x2 LCD usually has 8 parallel data pins with enable, and other two pins. And then there are other 16x2 modules which works on RS-232 or SPI directly. Check if flex LCD driver implements whatever type of LCD u r using.
I never used 3rd party drivers myself but developed my own drivers. It is very easy and quick.
But if u r seeing something on LCD i guess driver is correct but still no harm in checking one. It may be bcoz of data byte u r sending either LSB first while driver and LCD supports MSB first. Or in case of parrallel 8-bit line LCD, the order of bits in a byte may be incorrect.

The clock is not required for parallel 8-bit line LCD, the usual 16x2 alphanumeric LCD which PICDEM2+ board has (i have the older version of dev board). And in case of SPI based LCD, the clock is provided by MCU, check if u r ordering bits correctly in flex driver or there is no slave clock errors set in SPI peripheral for MCU.

The 16MHz crystal on PICDEM2+ board is for MCU, i.e. external precision oscillator for MCU.

Hope that helps.
 


First of all Thanks for the replay....
I m not using a PICDEM2 Board..i m using a mini board which consist of all port pin strips and a 16 mhz crystal..
i m giving data to lcd in 4 bit mode..

My lcd driver::

Code:
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7

#define LCD_E     PIN_D0
#define LCD_RS    PIN_D1
#define LCD_RW    PIN_D2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1     

//========================================

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


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2)); 
 output_bit(LCD_DB6, !!(nibble & 4));   
 output_bit(LCD_DB7, !!(nibble & 8));   

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.     

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);   
}   
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60); 
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7)); 

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif

Thank you....
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…