ITP
Advanced Member level 4
Hi,
I am facing a problem in interfacing an LCD with PIC16F876.
It works with proteus (ver6.3sp1). But with actual circuit it shows
some junk characters.
I am pasting the lcd.c file directly here. And the complete files I have attached in zip format with sch.
I am doing any Mistake.??? Kindly Help.
Thanks and Regards
Itp
#### LCD.C Starts Here############
/*************************************************************************
FILE: LCD.C
**************************************************************************/
/*************************************************************************
FUNCTIONS
**************************************************************************/
/*************************************************************************
FUNCTION: LCD_START
PARAMETERS: NONE
FEEDBACK: NONE
DESCRIPTION: SEND THE INITIALIZATION COMMANDS TO LCD
**************************************************************************/
void init_lcd(void)
{
output_bit(PIN_C5,0);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x32);
delay_ms(50);
lcd_command_out(0x28);
delay_ms(50);
lcd_command_out(0xe);
delay_ms(50);
lcd_command_out(0x2);
delay_ms(50);
lcd_command_out(0x1);
delay_ms(50);
}
/*************************************************************************
FUNCTION: LCD_CLEAR
PARAMETERS: NONE
FEEDBACK: NONE
DESCRIPTION: CLEAR LCD SCREEN
**************************************************************************/
void lcd_clear(void)
{
lcd_command_out(0x01);
}
/*************************************************************************
FUNCTION: LCD_POSIC
PARAMETERS: BYTE - NEW POSITION OF CURSOR
FEEDBACK: NONE
DESCRIPTION: MOVE THE CURSOR TO NEW POSITION ON LCD
**************************************************************************/
void lcd_posic(unsigned char position)
{
if (position > ((2 * LCD_COLS)-1))
position = 0;
if (position < LCD_COLS)
lcd_command_out(0x80 + position);
else
lcd_command_out(0xC0 + (position - LCD_COLS));
}
/*************************************************************************
FUNCTION: LCD_DISPLAY
PARAMETERS: BYTE - KEY, ON - ENABLE, OFF - DISABLE
CHANGE: BIT C = ON, BIT B = OFF
FEEDBACK: NONE
DESCRIPTION: TURN LCD DISPLAY ON/OFF
**************************************************************************/
void lcd_display(int1 key)
{
if (key)
lcd_command_out (0x0E);
else
lcd_command_out (0x0A);
}
/*************************************************************************
FUNCTION: LCD_CURSOR
PARAMETERS: BYTE - KEY, ON - ENABLE, OFF - DISABLE
CHANGE: BIT D = ON, BIT B = OFF
FEEDBACK: NONE
DESCRIPTION: TURN LCD CURSOR ON/OFF
**************************************************************************/
void lcd_cursor(int1 key)
{
if (key)
lcd_command_out (0x0F);
else
lcd_command_out (0x0C);
}
/*************************************************************************
FUNCTION: LCD_SHIFT_CURSOR
PARAMETERS: BIT - KEY, RIGHT / LEFT
FEEDBACK: NONE
DESCRIPTION: MOVE CURSOR TO LEFT OR RIGHT
**************************************************************************/
void lcd_shift_cursor(int1 key)
{
if (key)
lcd_command_out(0x14);
else
lcd_command_out(0x10);
}
/*************************************************************************
FUNCTION: LCD_AUTO_SHIFT_CURSOR
PARAMETERS: BIT - KEY, RIGHT/LEFT
CHANGE: BIT S - DONT MOVE THE SCREEN
FEEDBACK: NONE
DESCRIPTION: ESTABILISH THE AUTOMATIC SHIFT OF CURSOR
**************************************************************************/
void lcd_auto_shift_cursor(int1 key)
{
if (key)
lcd_command_out(0x07);
else
lcd_command_out(0x06);
}
/*************************************************************************
FUNCTION: LCD_PRINT
PARAMETERS: BYTE *STRING - (0 TERMINATED STRING)
FEEDBACK: NONE
DESCRIPTION: SEND A STRING TO LCD (ON CURRENT CURSOR POSITION)
**************************************************************************/
void lcd_print(unsigned char *string)
{
while (*string)
{lcd_data_out (*string++);}
}
/*************************************************************************
FUNCTION: LCD_PRINT_M
PARAMETERS: BYTE *STRING - (0 TERMINATED STRING)
BYTE - LINE
FEEDBACK: NONE
DESCRIPTION: SEND A CENTERED STRING ON SPECIFIC LINE OF LCD
**************************************************************************/
void lcd_print_m(unsigned char *string,unsigned char line)
{
unsigned char position,size;
if (line == 1)
position = 0;
else
position = LCD_COLS;
lcd_posic(position);
for (size=0; size < LCD_COLS; size++)
lcd_print(" ");
size = strlen(string)-1;
position = (LCD_COLS - size)/2;
if (line == 2)
position +=LCD_COLS;
lcd_posic(position);
lcd_print(string);
}
/*************************************************************************
FUNCTION: LCD_PRINT_WORD
PARAMETERS: WORD - VALUE, (0x0000 TO 0xFFFF)
BYTE - DIGITS, FORMATTED (0 TO 5 CHARACTERS)
FEEDBACK: NONE
DESCRICAO: PRINT AN INTEGER NUMBER (2 BYTES) ON DECIMAL FORM
**************************************************************************/
void lcd_print_word(unsigned int16 value,unsigned char digits)
{
const unsigned int16 divider[] = {1,10,100,1000,10000};
unsigned char i;
for (i= 5; i > digits;i--) value = value%divider;
while (i) {
lcd_data_out(value/divider[--i]+48);
value = value % divider;
}
}
/*************************************************************************
FUNCTION: LCD_PUTBYTE
PARAMETERS: BYTE - DATA, (0x00 TO 0xFF)
FEEDBACK: NONE
DESCRIPTION: SEND A BYTE ON HEXADECIMAL FORM TO LCD
**************************************************************************/
void lcd_putbyte(unsigned char dat)
{
unsigned char aux;
aux = dat/16;
lcd_data_out((aux > 9) ? (aux += 0x37) : (aux += 0x30));
aux = dat & 0xF;
lcd_data_out((aux > 9) ? (aux += 0x37) : (aux += 0x30));
}
/*************************************************************************
FUNCTION: LCD_PUTWORD
PARAMETERS: BYTE - DATA, (0 TO 65535D)
FEEDBACK: NONE
DESCRIPTION: SEND TWO BYTES ON HEXADECIMAL FORM TO LCD (0xNNNN)
**************************************************************************/
void lcd_putword(unsigned int16 dat)
{
lcd_putbyte((unsigned char) (dat/256));
lcd_putbyte((unsigned char) dat);
}
void lcd_command_out(unsigned char c) // Writes the command in A to LCD
{
output_bit(PIN_C7,0);
send_char(c);
}
void lcd_data_out(unsigned char c) // Writes the data in A to LCD
{
output_bit(PIN_C7,1);
send_char(c);
}
// Send a Command or data to lcd
void send_char(int8 ch)
{
output_bit(PIN_C5,0);
output_bit(PIN_C4,(ch & (1 << 4)));
output_bit(PIN_C3,(ch & (1 << 5)));
output_bit(PIN_C2,(ch & (1 << 6)));
output_bit(PIN_C1,(ch & (1 << 7)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
delay_ms(1);
output_bit(PIN_C4,(ch & (1 << 0)));
output_bit(PIN_C3,(ch & (1 << 1)));
output_bit(PIN_C2,(ch & (1 << 2)));
output_bit(PIN_C1,(ch & (1 << 3)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
}
void send_nibble(unsigned char ch)
{
output_bit(PIN_C5,0);
output_bit(PIN_C4,(ch & (1 << 0)));
output_bit(PIN_C3,(ch & (1 << 1)));
output_bit(PIN_C2,(ch & (1 << 2)));
output_bit(PIN_C1,(ch & (1 << 3)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
delay_ms(1);
}
####### LCD.C end HERE
I am facing a problem in interfacing an LCD with PIC16F876.
It works with proteus (ver6.3sp1). But with actual circuit it shows
some junk characters.
I am pasting the lcd.c file directly here. And the complete files I have attached in zip format with sch.
I am doing any Mistake.??? Kindly Help.
Thanks and Regards
Itp
#### LCD.C Starts Here############
/*************************************************************************
FILE: LCD.C
**************************************************************************/
/*************************************************************************
FUNCTIONS
**************************************************************************/
/*************************************************************************
FUNCTION: LCD_START
PARAMETERS: NONE
FEEDBACK: NONE
DESCRIPTION: SEND THE INITIALIZATION COMMANDS TO LCD
**************************************************************************/
void init_lcd(void)
{
output_bit(PIN_C5,0);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x33);
delay_ms(50);
lcd_command_out(0x32);
delay_ms(50);
lcd_command_out(0x28);
delay_ms(50);
lcd_command_out(0xe);
delay_ms(50);
lcd_command_out(0x2);
delay_ms(50);
lcd_command_out(0x1);
delay_ms(50);
}
/*************************************************************************
FUNCTION: LCD_CLEAR
PARAMETERS: NONE
FEEDBACK: NONE
DESCRIPTION: CLEAR LCD SCREEN
**************************************************************************/
void lcd_clear(void)
{
lcd_command_out(0x01);
}
/*************************************************************************
FUNCTION: LCD_POSIC
PARAMETERS: BYTE - NEW POSITION OF CURSOR
FEEDBACK: NONE
DESCRIPTION: MOVE THE CURSOR TO NEW POSITION ON LCD
**************************************************************************/
void lcd_posic(unsigned char position)
{
if (position > ((2 * LCD_COLS)-1))
position = 0;
if (position < LCD_COLS)
lcd_command_out(0x80 + position);
else
lcd_command_out(0xC0 + (position - LCD_COLS));
}
/*************************************************************************
FUNCTION: LCD_DISPLAY
PARAMETERS: BYTE - KEY, ON - ENABLE, OFF - DISABLE
CHANGE: BIT C = ON, BIT B = OFF
FEEDBACK: NONE
DESCRIPTION: TURN LCD DISPLAY ON/OFF
**************************************************************************/
void lcd_display(int1 key)
{
if (key)
lcd_command_out (0x0E);
else
lcd_command_out (0x0A);
}
/*************************************************************************
FUNCTION: LCD_CURSOR
PARAMETERS: BYTE - KEY, ON - ENABLE, OFF - DISABLE
CHANGE: BIT D = ON, BIT B = OFF
FEEDBACK: NONE
DESCRIPTION: TURN LCD CURSOR ON/OFF
**************************************************************************/
void lcd_cursor(int1 key)
{
if (key)
lcd_command_out (0x0F);
else
lcd_command_out (0x0C);
}
/*************************************************************************
FUNCTION: LCD_SHIFT_CURSOR
PARAMETERS: BIT - KEY, RIGHT / LEFT
FEEDBACK: NONE
DESCRIPTION: MOVE CURSOR TO LEFT OR RIGHT
**************************************************************************/
void lcd_shift_cursor(int1 key)
{
if (key)
lcd_command_out(0x14);
else
lcd_command_out(0x10);
}
/*************************************************************************
FUNCTION: LCD_AUTO_SHIFT_CURSOR
PARAMETERS: BIT - KEY, RIGHT/LEFT
CHANGE: BIT S - DONT MOVE THE SCREEN
FEEDBACK: NONE
DESCRIPTION: ESTABILISH THE AUTOMATIC SHIFT OF CURSOR
**************************************************************************/
void lcd_auto_shift_cursor(int1 key)
{
if (key)
lcd_command_out(0x07);
else
lcd_command_out(0x06);
}
/*************************************************************************
FUNCTION: LCD_PRINT
PARAMETERS: BYTE *STRING - (0 TERMINATED STRING)
FEEDBACK: NONE
DESCRIPTION: SEND A STRING TO LCD (ON CURRENT CURSOR POSITION)
**************************************************************************/
void lcd_print(unsigned char *string)
{
while (*string)
{lcd_data_out (*string++);}
}
/*************************************************************************
FUNCTION: LCD_PRINT_M
PARAMETERS: BYTE *STRING - (0 TERMINATED STRING)
BYTE - LINE
FEEDBACK: NONE
DESCRIPTION: SEND A CENTERED STRING ON SPECIFIC LINE OF LCD
**************************************************************************/
void lcd_print_m(unsigned char *string,unsigned char line)
{
unsigned char position,size;
if (line == 1)
position = 0;
else
position = LCD_COLS;
lcd_posic(position);
for (size=0; size < LCD_COLS; size++)
lcd_print(" ");
size = strlen(string)-1;
position = (LCD_COLS - size)/2;
if (line == 2)
position +=LCD_COLS;
lcd_posic(position);
lcd_print(string);
}
/*************************************************************************
FUNCTION: LCD_PRINT_WORD
PARAMETERS: WORD - VALUE, (0x0000 TO 0xFFFF)
BYTE - DIGITS, FORMATTED (0 TO 5 CHARACTERS)
FEEDBACK: NONE
DESCRICAO: PRINT AN INTEGER NUMBER (2 BYTES) ON DECIMAL FORM
**************************************************************************/
void lcd_print_word(unsigned int16 value,unsigned char digits)
{
const unsigned int16 divider[] = {1,10,100,1000,10000};
unsigned char i;
for (i= 5; i > digits;i--) value = value%divider;
while (i) {
lcd_data_out(value/divider[--i]+48);
value = value % divider;
}
}
/*************************************************************************
FUNCTION: LCD_PUTBYTE
PARAMETERS: BYTE - DATA, (0x00 TO 0xFF)
FEEDBACK: NONE
DESCRIPTION: SEND A BYTE ON HEXADECIMAL FORM TO LCD
**************************************************************************/
void lcd_putbyte(unsigned char dat)
{
unsigned char aux;
aux = dat/16;
lcd_data_out((aux > 9) ? (aux += 0x37) : (aux += 0x30));
aux = dat & 0xF;
lcd_data_out((aux > 9) ? (aux += 0x37) : (aux += 0x30));
}
/*************************************************************************
FUNCTION: LCD_PUTWORD
PARAMETERS: BYTE - DATA, (0 TO 65535D)
FEEDBACK: NONE
DESCRIPTION: SEND TWO BYTES ON HEXADECIMAL FORM TO LCD (0xNNNN)
**************************************************************************/
void lcd_putword(unsigned int16 dat)
{
lcd_putbyte((unsigned char) (dat/256));
lcd_putbyte((unsigned char) dat);
}
void lcd_command_out(unsigned char c) // Writes the command in A to LCD
{
output_bit(PIN_C7,0);
send_char(c);
}
void lcd_data_out(unsigned char c) // Writes the data in A to LCD
{
output_bit(PIN_C7,1);
send_char(c);
}
// Send a Command or data to lcd
void send_char(int8 ch)
{
output_bit(PIN_C5,0);
output_bit(PIN_C4,(ch & (1 << 4)));
output_bit(PIN_C3,(ch & (1 << 5)));
output_bit(PIN_C2,(ch & (1 << 6)));
output_bit(PIN_C1,(ch & (1 << 7)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
delay_ms(1);
output_bit(PIN_C4,(ch & (1 << 0)));
output_bit(PIN_C3,(ch & (1 << 1)));
output_bit(PIN_C2,(ch & (1 << 2)));
output_bit(PIN_C1,(ch & (1 << 3)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
}
void send_nibble(unsigned char ch)
{
output_bit(PIN_C5,0);
output_bit(PIN_C4,(ch & (1 << 0)));
output_bit(PIN_C3,(ch & (1 << 1)));
output_bit(PIN_C2,(ch & (1 << 2)));
output_bit(PIN_C1,(ch & (1 << 3)));
delay_us(10);
output_bit(PIN_C5,1);
delay_us(10);
output_bit(PIN_C5,0);
delay_ms(1);
}
####### LCD.C end HERE