Ich grins mich eins - mir gehts da wie Dir und dem LCD: wir brauchen alle mal ein paar waits wenns kompliziert wird *gg*... Da ich das erst richtig verarbeiten muss, erbitte ich mir etwas Zeit, bis ich wieder Rückmeldung gebe ..
Spass beiseite. Ich habe zwar keine Assemblerlösung. Aber in Assembler werden ja ähnliche Routinen nötig wie in C - und da kann ich ein bisschen was zu den Waits beitragen. Im folgenden Code sind die "waits" - heissen dort
......_delay_us (parameter)
rot hervorgehoben. Die Delays habe ich vor Jahren angepasst für 20 MHz Controllertakt (ist ja aber in µs angegeben) - und diese Routinen laufen bei mir so auf irgendwelchen, möglichst günstigen 2x16-LCDisplays. Vielleicht hilft Dir das ein bisschen weiter?
Code:// Erweiterte Fassung mit Routine für selbst definierte Zeichen // Stand = Erweiterung von lcd-routines.h und lcd-routines.c // vom 11. Apr. 2012 // 28 Nov 2012 16:24 Leichte Korrekturen // 27 Juni 2015, 19:27 Datenausgabe PC0..PC3, Steuerport PD // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial // Die Pinbelegung ist über defines in lcd-routines.h einstellbar #include <avr/io.h> //#include "lcd-routines.h" #include "lcd_162_xt_ALCo.h" #include <util/delay.h> #include <avr/eeprom.h> // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // sendet ein Datenbyte an das LCD void lcd_data(unsigned char temp1) { LCD_PORT |= (1<<LCD_RS); // RS auf 1 setzen lcd_send(temp1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // sendet einen Befehl an das LCD void lcd_command(unsigned char temp1) { LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen lcd_send(temp1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Eigentliche LCD-Zugriffs-Funktion; 4-Bit-Modus void lcd_send(unsigned char data) { // oberes Nibble setzen LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F); _delay_us(15); lcd_enable(); // unteres Nibble setzen LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F); _delay_us (15); lcd_enable(); _delay_us (60); LCD_PORT &= 0xF0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // erzeugt den Enable-Puls void lcd_enable(void) { LCD_PORT |= (1<<LCD_EN1); _delay_us (20); // kurze Pause // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern // http://www.mikrocontroller.net/topic/80900 LCD_PORT &= ~(1<<LCD_EN1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Initialisierung: // Muss ganz am Anfang des Programms aufgerufen werden. void lcd_init(void) { LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN1); // Port auf Ausgang schalten // muss 3mal hintereinander gesendet werden zur Initialisierung _delay_us (40); LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x03; lcd_enable(); _delay_us (15); lcd_enable(); _delay_us (11); lcd_enable(); _delay_us (11); LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x02; _delay_us (11); lcd_enable(); _delay_us (11); // 4Bit / 2 Zeilen / 5x7 lcd_command(CMD_SetIFOptions | 0x08); // Display ein / Cursor aus / kein Blinken lcd_command(CMD_SetDisplayAndCursor | 0x04); // inkrement / kein Scrollen lcd_command(CMD_SetEntryMode | 0x02); lcd_clear(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sendet den Befehl zur Löschung des Displays void lcd_clear(void) { lcd_command(CLEAR_DISPLAY); _delay_us (15); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Schreibt einen String auf das LCD void lcd_string(char *data) { while(*data) { lcd_data(*data); data++; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //String aus EEPROM laden und an LCD senden void lcd_eep_string(const unsigned char *data) { // unsigned char c; while(1) // { // c = eeprom_read_byte(data); // if(c==0) return; // lcd_data(c); // data++; // } } // Ende void lcd_eep_string(const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Schreibt ein Zeichen in den Character Generator RAM // Daten liegen direkt im RAM void lcd_generatechar(uint8_t code, const uint8_t *data) { // lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen for (uint8_t i=0; i<8; i++) // Bitmuster übertragen { // lcd_data(data[i]); // } // } // Ende void lcd_generatechar(uint8_t code, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -







Zitieren


Lesezeichen