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.

LCD Problem in CCS Compiler

Status
Not open for further replies.

ITP

Advanced Member level 4
Joined
Jul 11, 2001
Messages
116
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Activity points
1,136
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 must say that I am no expert for CCS (I use Hi-Tech for PIC) but when I look at your send_char function I believe that you reverse the order of the bits that you send to your LCD.

Bit 7 -> LCD Bit 0, Bit 6 -> LCD Bit 1 ...

Bit 3 -> LCD Bit 0, Bit 2 -> LCD Bit 1 ...

I believe it should be like this:
Bit 7 -> LCD Bit 3, Bit 6 -> LCD Bit 2 ...

Bit 3 -> LCD Bit 3, Bit 2 -> LCD Bit 2 ...

Also when I look at your lcd_data_out function I see that it expects a single byte as argument and not a string like you are using in your lcd_test.c.

You should also to a look at the CCS forum at:
https://www.ccsinfo.com/forum

Hope this helps, best regards
 

Hi C-Man,

Thanks for the link. I have searched that forum and got a usefull link. I will try with this.

The order of sending the bits to LCD is correct as I connected it that way. It simulates in Proteus.
PIN_C7= RS
PIN_C5= ENABLE
PIN_C4= D4
PIN_C3= D5
PIN_C2= D6
PIN_C1= D7

RW is tied low.

The link I got may be usefull to others also.

**broken link removed**

I also request the members kindly help me to sortout the problem in posted code.

Thanks and Regards
Itp
 

Hi C-Man,

That link worked for me !!!.

:D

Thanks and Regards
Itp
 

Maybe you should increse time in void send_char(int8 ch) from delay_ms(1) to (2).
 

Hi ITP,

It´s not usual nor practical to assign the PIC Data bits sharing nibbles in this way:
The order of sending the bits to LCD is correct as I connected it that way. It simulates in Proteus.
PIN_C7= RS
PIN_C5= ENABLE
PIN_C4= D4
PIN_C3= D5
PIN_C2= D6
PIN_C1= D7

RW is tied low.

Using 4-bit LCD mode, to send a byte to the LCD you need to handle such byte as two swapped nibbles, so using the following pin assignements it´s easy to code because you are using the whole Hi nibble of PortC as Data lines.

PIN_C7= D7 LCD
PIN_C6= D6 LCD
PIN_C5= D5 LCD
PIN_C4= D4 LCD

PIN_C3= RS
PIN_C2= ENABLE

As an example of this, following you get a piece of code needed to send a byte to LCD

void lcd_send_byte( BYTE address, BYTE n )
{
lcd.RS = 0;
lcd.RS = address;
delay_ms(7);
lcd.ENABLE = 0;
lcd_send_nibble(n >> 4); // First Hi nibble
lcd_send_nibble(n & 0xf);// Then Lo nibble
}

Hope you understand what I mean.

Best regards,
humber555
 

Hi guys,

Any library for graphics LCD, not character one? C or assembly for 8051 series.

Thx i a
 

Hi Humber555, I got what you mean. Thanks for the reply. I cannot change the connections as I am working on a PCB. The link I mentioned in the earlier post works for me.

rozerf, You can search this forum for GLCD.

Thanks and Regards
Itp
 

I think you might use standart ccsc lcd fonctions for driving charecter LCDs .And one more thing you have to use RW pin. because standard lib fonction use this,otherwise your actual curciut woldn't work. :!:
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top