CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem with 4 bit lcd with 18f4520

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jhon_s



Joined: 09 Jun 2016
Posts: 3

View user's profile Send private message

problem with 4 bit lcd with 18f4520
PostPosted: Thu Jun 09, 2016 11:44 pm     Reply with quote

I am new for pic programming. I wrote code and test it on Proteus. My 8 bit lcd code is working properly but having issue with 4 bit mode. I also checked that with my code command and data reached at lcd data pins correctly.
Still i dont get the output, plz help me.
jhon_s



Joined: 09 Jun 2016
Posts: 3

View user's profile Send private message

PostPosted: Thu Jun 09, 2016 11:46 pm     Reply with quote

my code is given below,,

Code:

#include <main.h>

#define rs pin_c0
//#define rw pin_c1
#define en pin_c2

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

void lcd_send_nibble(unsigned char 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));   
   
    output_high(en);
    output_low(en);
    delay_ms(2);
}

void lcd_write(unsigned char data)
{
lcd_send_nibble(data >> 4);
lcd_send_nibble(data & 0x0f);
delay_ms(2);
}

void lcd_cmd(unsigned char cmd)
{
output_low(rs);
lcd_write(cmd);
}

void lcd_init( )
{
//lcd_cmd(0x30);
delay_ms(10);
lcd_cmd(0x20);
lcd_cmd(0x28);
lcd_cmd(0x0e);
lcd_cmd(0x01);
lcd_cmd(0x06);
lcd_cmd(0x80);
delay_ms(15);
}

void lcd_char(unsigned char ch)
{
output_high(rs);
lcd_write(ch);
}

void main()
{
lcd_init();
delay_ms(10);
printf(lcd_char,"CCS_FORUM");


   while(TRUE)
  {
  }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Fri Jun 10, 2016 1:06 am     Reply with quote

First, _forget Proteus_.
Do a search here, and look at the 'sticky' at the top of the forum. Proteus will mislead you in a big way about whether code works or not. Forget it. Forget it. Forget it. _It wastes your time, and ours_......

The PIC has internally an instruction, that in just one cycle, can test a bit in a value, and return a 'true/false' result. Now this is a 'PIC specific' instruction, but you might as well use it. CCS give you access to this with the 'bit_test' instruction.
So:

output_bit(LCD_DB4, !!(nibble & 1));

Codes more tidily as:

output_bit(LCD_DB4, bit_test(nibble,0));

I think it is tidier to use the latter form. The compiler though is smart, and does actually substitute the bit_test code..... Smile

The reason you have this, is that PCM_programmer, wrote 'flex_lcd', before CCS added this instruction.

Then look at the LCD data sheet. Most _require_ a pause, after power is applied, before they can accept any commands or data. Typically with the original Hitachi controller, 90mSec. However a lot of the clone controllers need more, and also this time only begins when the power supply reaches their operating voltage, which is typically a lot higher than that needed for the PIC. The first instruction in the main, on any code expecting to talk to an LCD, should be something like 'delay_ms(500)'. Trying to write to the LCD before this will stop it working. In the real world, this would prevent your code from working, but here Proteus will tell you things work, when they won't. Back to comment at the top.....

Other one that could be causing grief, is the R/W line. This needs to be pulled _low_ on the LCD, if it is not being controlled by the CPU. If this is left floating, you can't write to the LCD.

Then how long does the EN pulse need to be to latch the data?.

output_high(en);
output_low(en);

For most displays the minimum E pulse is perhaps 500nSec, or 1uSec. It is very probable that this is too quick. If you look at the code you have partially used, there is a 2uSec pause, but also a 1uSec pause after the data is written, before the latch is operated.

Then there is an enormous problem with your initialisation. _READ THE LCD DATA SHEET_....

If you look at flex_lcd, you will see it waits 5mSec between the initialisation bytes. The reason is this line after the first byte is written:

"Wait more than 4.1ms"

From the original Hitachi sheet.

Then your initialisation sequence looks wrong. The sequence that has to be sent, is three _nibbles_ of 0x03, then one of 0x02, followed by the initialisation sequence:

0x28 (for a 2 line display)
0x0E (display on, cursor on, no blink)
0x01 (clear display)
0x06 (cursor to auto increment, and not shift)

The first nibbles need to be sent as nibbles, with the delays. You can't send these as bytes, without the delays.

sending '0x20 0x28, just means the first 0x20, is thrown away.

Sending 0x80, means the next byte will be treated as the address to talk to in the DDRAM. Why are you sending this?.
jhon_s



Joined: 09 Jun 2016
Posts: 3

View user's profile Send private message

PostPosted: Fri Jun 10, 2016 4:42 am     Reply with quote

Thank you sir. I got proper output.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group