Electronic – Weird output on 16X2 JHD162A LCD display

atmegacinterfacelcd

I am learning interfacing of Atmega 16a with 16X2 LCD.
I have a written a header file for routines which will used frequently and every time I want to interface with LCD using Atmega 16a I use this header file.

here is my LCD header file:

#include<stdlib.h>
#include<avr/io.h>
#include<util/delay.h>
int cx=1;
int cy=1;
void LCD_Send(unsigned char c,unsigned char DC)
{

    if(DC==0)
    {
        PORTC=0x0F & (c>>4);
        PORTC=PORTC|(1<<5);
        _delay_ms(1);
        PORTC=PORTC & (~(1<<5));
        _delay_ms(1);
        PORTC=0x0F & (c);
        PORTC=PORTC | (1<<5);
        _delay_ms(1);
        PORTC=PORTC & (~(1<<5));
        _delay_ms(1);
    }
    else if(DC==1)
    {
        PORTC=0x0F & (c>>4);
        PORTC=PORTC | (1<<7);
        PORTC=PORTC|(1<<5);
        _delay_ms(1);
        PORTC=PORTC & (~(1<<5));
        _delay_ms(1);
        PORTC=0x0F & (c);
        PORTC=PORTC | (1<<7);
        PORTC=PORTC | (1<<5);
        _delay_ms(1);
        PORTC=PORTC & (~(1<<5));
        _delay_ms(1);
    }
    return ;
}
void LCD_init(void)
{
    DDRC=0b11101111;
    LCD_Send(0x01,0);
    LCD_Send(0x0F,0);
    LCD_Send(0x28,0);
    cx=1;cy=1;
    return ;
}
void LCD_Send_String(char* s)
{
    for(int i=0;s[i]!='\0';i++)
    {
        LCD_Send(s[i],1);
        if(cx==16)
        {
            cx=1;cy++;
            LCD_Send(0xC0,0);
        }
        else
        cx++;
    }
    return ;
}
void LCD_GotoXY(unsigned int x,unsigned int y)
{
    if(y==1)
    {
        char addr=0x80;
        addr=addr+(x-1);
        LCD_Send(addr,0);
    }
    else if(y==2)
    {
        char addr=0xC0;
        addr=addr+(x-1);
        LCD_Send(addr,0);
    }    
    cx=x; cy=y;
    return ;
}
void LCD_Print(int data,unsigned int x,unsigned int y)
{
    char string[10];
    LCD_GotoXY(x,y);
    itoa(data,string,10);
    LCD_Send_String(string);
    return ;
}

Here RS,R/W and E are PC7,PC6 and PC5 respectively, DB4,DB5,DB6,DB7 are PC0,PC1,PC2,PC3 respectively. I am using 4 bit mode for input.

here is my main.c file (the code which will be run on the microprocessor):

#include"lcd.h"
int main(void)
{
    LCD_init();
    char s[20]="1234567890123456789";
    LCD_Send_String(s);
    return 0;
}

When I flash the memory with the HEX file then reset the LCD is displaying fine

figure1

Then when I reset later it displays random variables(infact I can see that the second line doesnt change at all, it means that the screen is not cleared but a command was written to LCD_init() to clear screen)

figure2

I am pretty sure that nothing is wrong with board and the connections because it works with other header files, I am pretty sure that it is a fault in my code.
I would really thankful if anyone help me fixing this code
If i reset again it displays the correct sequence as in first image

Best Answer

Your problem is that the display keeps its state during MCU reset. When cold-booting, the initial data mode is 8-bit which you immediately switch to 4-bit which reads data with a pair of EN pulses.

When you reset the MCU, you do not know whether even or odd number of EN pulses were sent. So you have to somhow reset the display even if it does not have reset pin.

This can be done by sending 0x33 0x33 (in 8-bit mode it will mean 4-times switch to 8-bit, in 4-bit mode it will mean once or twice switch to 8-bit). Then you can be sure that you always start from the same state.

Then proceed with regular 0x32 (or 4-bit 0x02 if you have single 4-bit write function), 0x28 to get into 4-bit 2-line mode.