'init codes not working on sitronix' st7920 LCD12864B

while learning how to control a LCD 12864B from a PIC16F84A, I found an unexpected behaviour in init codes. I better explain the problem on a comment in the submitted code. I hope someone can give a clarifying reply. Here it is my LCD.c file:

`#include "Includes.h"`


void ToggleEpinOfLCD(void)
{
    LCD_E = 1;                // Give a pulse on E pin
    __delay_us(E_Delay);      // so that LCD can latch the
    LCD_E = 0;                // data from data bus
    __delay_us(E_Delay);    
}


void WriteCommandToLCD(unsigned char Command)  
{
    LCD_RS = 0;               // It is a command

    PORTB &= 0xF0;            // Make Data pins zero
    PORTB |= ((Command>>4)&0x0F); // Write Upper nibble of data
    ToggleEpinOfLCD();        // Give pulse on E pin    

    PORTB &= 0xF0;            // Make Data pins zero
    PORTB |= (Command&0x0F); // Write Lower nibble of data
    ToggleEpinOfLCD();        // Give pulse on E pin
}

void WriteDataToLCD(char LCDChar)  
{
    LCD_RS = 1;               // It is data
    PORTB &= 0xF0;            // Make Data pins zero
    PORTB |= ((LCDChar>>4)&0x0F);  // Write Upper nibble of data
    ToggleEpinOfLCD();        // Give pulse on E pin    

    PORTB &= 0xF0;            // Make Data pins zero
    PORTB |= (LCDChar&0x0F); // Write Lower nibble of data
    ToggleEpinOfLCD();        // Give pulse on E pin
}


void InitLCD(void)
{ 
    // Firstly make all pins output
    LCD_E                = 0;   // E  = 0
    LCD_RS               = 0;   // RS = 0
    LCD_Data_Bus_D0      = 0;   // Data bus = 0
    LCD_Data_Bus_D1      = 0;   // Data bus = 0
    LCD_Data_Bus_D2      = 0;   // Data bus = 0
    LCD_Data_Bus_D3      = 0;   // Data bus = 0
    LCD_E_Dir            = 0;   // Make Output
    LCD_RS_Dir           = 0;   // Make Output
    LCD_Data_Bus_Dir_D0  = 0;   // Make Output
    LCD_Data_Bus_Dir_D1  = 0;   // Make Output
    LCD_Data_Bus_Dir_D2  = 0;   // Make Output
    LCD_Data_Bus_Dir_D3  = 0;   // Make Output

    ///////////////// Reset process //////////////

// On page 29 of the Sitronix' ST7920 datasheet, the display init procedure for 4 bits communication is the following:
//      Wait 40 ms after power on
// labels here  RS  R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0     HEX
// function set  0   0   0   0   1   0   X   X   X   X      20
//      Wait > 100 us
// function set  0   0   0   0   1   0   X   X   X   X      20
//               0   0   X   0   X   X   X   X   X   X      00
// this to me sounds correct, as 20h it's the code that sets the display on 4-bit mode
// but this doesn't work... WHY??
// Other people at this point suggest to send a 0x03 twice and then a 0x02, separated by a 500 us delay
// but I found it suffices to send a single 0x02 as below.
// Can someone please explain this, mainly as the official sitronix codes are involved?
__delay_ms(40);

    WriteCommandToLCD(0x02); //select DDRAM, cursor move to dx address counter +1

    /////////////////// Reset process end //////////


    WriteCommandToLCD(0x20);    //function set 4 bits mode
    WriteCommandToLCD(0x0c);    //display on,cursor off,blink off
    WriteCommandToLCD(0x01);    //clear display
    __delay_ms(2);  // 
    WriteCommandToLCD(0x06);    //entry mode, set increment
}



void ClearLCDScreen(void)       // Clear the Screen and return cursor to zero position
{
    WriteCommandToLCD(0x01);    // Clear the screen
    __delay_ms(2);              // Delay for cursor to return at zero position
}

For sake of completeness, I add the schematic image. enter image description hereBe well!

lcd


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source