|
|
View previous topic :: View next topic |
Author |
Message |
jhon_s
Joined: 09 Jun 2016 Posts: 3
|
problem with 4 bit lcd with 18f4520 |
Posted: Thu Jun 09, 2016 11:44 pm |
|
|
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
|
|
Posted: Thu Jun 09, 2016 11:46 pm |
|
|
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
|
|
Posted: Fri Jun 10, 2016 1:06 am |
|
|
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.....
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
|
|
Posted: Fri Jun 10, 2016 4:42 am |
|
|
Thank you sir. I got proper output. |
|
|
|
|
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
|