You appear to be using a 1602 LCD which is sold under many different names. You are not following the timing diagram. The timing diagram shows 5 distinct times where the signals change, I have labeled them A-E.
For some controllers, tAS can be zero, and A and B can be simultaneous. You need to look at the timing diagram for your exact controller. (If you want people to help, you should post this type of information)
E would be the earliest that the next cycle could start. If you are not starting another cycle, you still may want to set all signals to an inactive state. but this is optional.
For D, you must only change the Enable bit, or you will violate the hold on RS and/or RW.


https://focuslcds.com/content/ST7066Uv25.pdf
Above is the datasheet for my controller, it has been cloned by many others (actually this may be a clone), others may be slightly different.
Use good programming practices so people can follow what you did. Define your bits.
My setup has an I2C interface using 4-bit mode on the LCD, so, I am unable to test this. There may be errors, but the general flow should be correct.
// HW Port Bits
#define LCD_EN 0b00000100 // Enable bit
#define LCD_RW 0b00000010 // Read/Write bit
#define LCD_RS 0b00000001 // Register select bit, 0 = Instr, 1 = Data
// Instruction control bits
#define LCD_INSTR_CLEAR_DISP 0x01
#define LCD_INSTR_RETURN_HOME 0x02
#define LCD_INSTR_ENTRY_MODE_SET 0x04
#define LCD_INSTR_DISP_ON_OFF 0x08
#define LCD_INSTR_CURS_DISP_SHIFT 0x10
#define LCD_INSTR_SET_FUNCT 0x20
#define LCD_INSTR_SET_CGRAPH_ADDR 0x40
#define LCD_INSTR_SET_DATA_ADDR 0x80
// Bit definitions for Display on/off
#define LCD_DISPLAY_ON 0x04
#define LCD_DISPLAY_CURS 0x02
#define LCD_DISPLAY_BLINK 0x01
// Bit definitions for Cursor shift
#define LCD_CURS_SHIFT_RIGHT 0x04
// Bit definitions for Set Function
#define LCD_FUNCTION_8BIT 0x10
#define LCD_FUNCTION_2LINE 0x08
#define LCD_FUNCTION_5x11 0x04
main()
{
// Setup ports
TBD
// Clear display
WriteLcdInstr( LCD_INSTR_CLEAR_DISP );
// Display ON
WriteLcdInstr( LCD_INSTR_DISP_ON_OFF | LCD_DISPLAY_ON );
// Write some text
WriteLcdData( 'H' );
WriteLcdData( 'e' );
WriteLcdData( 'l' );
WriteLcdData( 'l' );
WriteLcdData( 'o' );
}
WriteLCDInstr( uint8_t u8Instr )
{
PORTE = LCD_RS; // A in timing diagram
delay_us( 1 );
PORTE = LCD_RS | LCD_EN; // B in timing diagram
delay_us( 1 );
PORTD = u8Instr ; // C in timing diagram
delay_us( 1 );
PORTE = LCD_RS; // D in timing diagram
delay_us( 1 );
PORTE = 0; // E in timing diagram
// Longer delay required for some instructions
if ( u8Instr <= LCD_INSTR_RETURN_HOME )
delay_us( 1520 );
}
WriteLCDData( uint8_t u8Data )
{
PORTE = 0; // A in timing diagram
delay_us( 1 );
PORTE = LCD_EN; // B in timing diagram
delay_us( 1 );
PORTD = u8Data; // C in timing diagram
delay_us( 1 );
PORTE = 0; // D in timing diagram
delay_us( 1 );
// E (no change)
}