Hi,
@ALLPIC,
write a byte to the LCD in 4 bit mode
Return :- Nothing
Argument :- Byte
*********************************************/
void lcd_write(unsigned char c)
{
union chartype x;
unsigned char p_data;
x.byte= c;
LCD_D4 = x.part.bit0;
LCD_D5 = x.part.bit1;
LCD_D6 = x.part.bit2;
LCD_D7 = x.part.bit3;
LCD_E = 1;
DelayUs(200);
LCD_E = 0;
DelayUs(200);
}
Yes, you seem to writing only lower nibble of the byte received. Then all your code calls the lcd_write() function twice, once for upper nibble & then for lower nibble. It is ok, no doubt, but is little inefficient in terms of code & speed
We can write the same function as,
#define LCD_DATA_PORT LATB
#define LCD_DATA_MASK 0b11110000 // Lower 4-bits as DB7-DB4
#define LCD_DATA 1
#define LCD_CMD 0
void lcd_write_nibble( unsigned char nib )
{
LCD_DATA_PORT &= LCD_DATA_MASK; // Make sure data lines are clear
LCD_DATA_PORT |= nib; // Writing nibble
LCD_E = 1;
NOP();
NOP();
LCD_E = 0; // Strobe EN line
DelayUs( 200 ); // Inter-nibble delay
}
void lcd_write( bool mode, unsigned char c )
{
if( LCD_CMD == mode ) { // Command
LCD_RS = 0;
} else { // Data
LCD_RS = 1;
}
lcd_write_nibble( c >> 4 ); // Upper nibble first
lcd_write_nibble( c & 0x0f ); // Lower nibble now
DelayUs( 200 ); // Inter-byte delay
}
Now you can easily call this from anywhere, whether you're writing command or data.
e.g. For clearing LCD, lcd_write( LCD_CMD, 0x01 ) or
For printing a char, lcd_write( LCD_DATA, 'c' )
I also suggest you that take another look at your code,there are few other bits of code which can be optimized. In my opinion a good code, is the one which passes through the compiler with all optimizations on & comes out without getting much optimized because you've written code in optimized way in the first place.
Hope that helps,
sam_des