I tried interfacing lcd with atmega16 my lcd is jhd 162A.I have attached code as well as schematic.whenever I connect the appropriate pins only black spots are seen, not what i intended to display.I couldnt what my problem was.I have also attached schematic.!
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000L
#define lcd_data PORTC
#define control PORTB
#define rs PB2
#define rw PB1
#define en PB0
void lcd_init (void);
void lcd_command(unsigned char cmd);
void lcd_write(unsigned char data);
void lcd_string(unsigned char *str);
void dis_cmd(char cmd_value);
void dis_write(unsigned char data);
int main()
{
DDRB = 0xFF;
DDRC = 0xFF;
lcd_init();
_delay_ms(50);
_delay_ms(1);
lcd_str("PROGRAMMING");
_delay_ms(50);
dis_cmd(0xc0);
lcd_str("IS FUN");
return 0;
}
void lcd_init (void)
{
dis_cmd(0x02); //initialises lcd on 4 bits mode
_delay_ms(1);
dis_cmd(0x28); //initialises lcd to use 2 line and 5*7 matrix ie 16*2 lcd on 8 bits
_delay_ms(1);
dis_cmd(0x01);//clears lcd screen
_delay_ms(1);
dis_cmd(0x0E);//display ON cursor ON
_delay_ms(1);
dis_cmd(0x80);//cursor is set on the 1st line
_delay_ms(1);
return;
}
void lcd_command(unsigned char cmd)
{
lcd_data =cmd;
control = (0<<rs)| (0<<rw) | (1<<en); // setting rs to 0 is command mode when rw=0 write mode
_delay_ms(1);
control = (0<<rs)| (0<<rw) | (0<<en);
_delay_ms(50);
// 2ta control command is used for the high to low transition of enable as the code works on the falling
// edge of the enable en
return;
}
void lcd_write(unsigned char data)
{
lcd_data= data;
control = (1<<rs)| (0<<rw) | (1<<en); // setting rs to 0 is command mode when rw=0 write mode
_delay_ms(1);
control = (1<<rs)| (0<<rw) | (0<<en);
_delay_ms(50);
return;
}
void dis_write(unsigned char data)
{
char data1;
data1 = data & 0xF0; //mask lower nibble because PA4-PA7 pins are used.
lcd_write(data1);
data1 = ((data<<4) & 0xF0); //shift 4-bit and mask
lcd_write(data1);
return;
// send to LCD
}
void lcd_str(unsigned char *str)
{
int i = 0;
while(str[i] != '\0')
{
dis_write(str[i]);
i++;
}
return;
}
void dis_cmd(char cmd_value)
{
char cmd_value1;
cmd_value1 = cmd_value & 0xF0; //mask lower nibble because PB4-PA7 pins are used.
lcd_command(cmd_value1); // send to LCD
cmd_value1 = ((cmd_value<<4) & 0xF0); //shift 4-bit and mask
lcd_command(cmd_value1); // send to LCD
}
I think you are not performing the required init sequence. In lcd_init()
you start by sending the function set.
However, the display awaits a sequence before that like this:
I am not sure how this is handled using 4-bit interface, but i think thats why DB3-0 are "don't care". You probably just have to apply DB7-4 on your 4-bit bus (read the datasheet).
I would wait for several hundred milliseconds on startup to make sure Vcc is stable. Then follow the reset sequence with relaxed timing like
PowerOn
Wait 200ms
Send Instruction
Wait 20ms
Send Instruction
Wait 5ms
Send Instruction
Wait 5ms
Send Function Set
...
Since you are not polling the busy flag, I would wait at least 1ms between all following instructions.