Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC18F4550 LCD Interfacing.

Status
Not open for further replies.

Praveen Kumar P S

Member level 4
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.
 

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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top