Mahlzeit

Ne Lösung kann ich dir nicht wirklich anbieten, nur ein paar Gedanken, wobei mein c etwas eingerostet ist...

Das viele hinundher gespringsel ist aufm PC ganz ok, auf nem AVR kostet sowas eeeeleend Zeit.

Wasn das?
Code:
void LCD_string(char *string)
{
	while(*string)
	{
		LCD_data(*string);
		string++;
	}
}
Hat aber eher nix mit dem einzelnen Zeichen zu tun

In lcd_enable wartest 3us, erscheint mir was wenig, kann mich aber auch irren.

Du führst in LCD_init schon LCD_on/clear aus, brauchst nicht nochmal in lcd_asm.

Schreib das init für den 4 bit modus 2mal, nutz deine lcd_cmd Funktion dafür, aber frag mich nie warum.... Schau ins Datenblatt vom Controller, ob 5ms nachm modus setzen reichen tun, dito für alle anderen cmds.

Klingt insgesamt nach nem Timing oder init Problem, schreibst ja mit LCD-data nur ein byte. Probier das mitm Modus 2x setzen und danach mit länger warten bei den einzelnen cmds/datenbytes.

Viel Glück