hallo,
also nach wochen des codens hab ich nun das erschaffen:
nun funktioniert das display mit diesem Code nicht, es kommen nur 2 schwarze Balken. (generell geht das display schon).Code:#include <avr/io.h> #define LCD_PORT PORTD #define LCD_DATA0_PORT LCD_PORT #define LCD_DATA1_PORT PORTB #define LCD_DATA2_PORT LCD_PORT #define LCD_DATA3_PORT LCD_PORT #define LCD_RS_PORT LCD_PORT #define LCD_RW_PORT LCD_PORT #define LCD_E_PORT LCD_PORT #define LCD_RS 4 #define LCD_RW 5 #define LCD_E 6 #define DB0 7 #define DB1 0 #define DB2 2 #define DB3 3 void toggle_e(void) { LCD_E_PORT |= _BV(LCD_E); asm volatile ("rjmp 1f\n 1:"); //warte 500ns 0,543 us LCD_E_PORT &= ~_BV(1 << LCD_E); } void delay(unsigned int count) { asm volatile ("rjmp 1f\n 1:"); //warte 500ns 0,543 us asm volatile ("rjmp 1f\n 1:"); //warte 500ns 0,543 us // also 1 us } void busy(void) { char dataH; char dataL; LCD_RW_PORT |= _BV(LCD_RW); LCD_RS_PORT &= ~_BV(LCD_RS); DDRD = 0xF7; //PD3 als Eingang definieren 0b11110111 LCD_E_PORT |= _BV(LCD_E); // LCD_E auf high do{ __asm__ __volatile__( "rjmp 1f\n 1:" ); //delay (500ns) dataH = PIND; //zuerst hohes Nibble lesen LCD_E_PORT &= ~_BV(LCD_E); __asm__ __volatile__( "rjmp 1f\n 1:" ); //delay LCD_E_PORT |= _BV(LCD_E); __asm__ __volatile__( "rjmp 1f\n 1:" ); //delay dataL = PIND; //lese niederes Nibble LCD_E_PORT &= ~_BV(LCD_E); //Dieser Code liest neben dem Busy-Flag gleich noch den Adresszähler aus }while(dataH & (1<<DB3)); //while(PIND & (1<<DB3)) {} // solange warten, bis DB3 (busyFlag) auf 0 //LCD_E_PORT &= ~_BV(LCD_E); // LCD_E auf low } int main() { DDRD = 0xFF; DDRB = 0xFF; delay(20000); //warte 20 ms (20000us) LCD_DATA1_PORT |= _BV(DB1); LCD_DATA0_PORT |= _BV(DB0); toggle_e(); delay(5000); //mehr als 4,1 ms warten (4992) toggle_e(); delay(200); // es muss mehr als 100 us gewartet werden toggle_e(); delay(200); // es muss mehr als 100 us gewartet werden LCD_DATA0_PORT &= ~_BV(DB0); //LCD_DATA0_PORT &= ~_BV(DB0); //PORTD = 0x20>>4; //entspricht 0b00100000 toggle_e(); delay(100); //mehr als 100us warten busy(); LCD_RS_PORT &= ~_BV(LCD_RS); LCD_RW_PORT &= ~_BV(LCD_RW); //Daten als Befehl zu deuten sind. Dies erfolgt durch RS=0 und RW=0 //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT = _BV(DB1); //1 -> high nibble 0b0010 (36) von 40 LCD_DATA0_PORT &= ~_BV(DB0); //0 // macht insgesamt 4 + 36 = 40 -> 0x28 toggle_e(); LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT = _BV(DB2); //1 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0bxxxx0100 (4) von 40 LCD_DATA0_PORT &= ~_BV(DB0); //0 toggle_e(); //In diesem Fall ist data = 0x28, wie es bereits oben erwähnt wurde. //Dann werden alle Datenpins wieder auf logisch '0' gesetzt. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 LCD_DATA0_PORT &= ~_BV(DB0); //0 // Als nächstes soll das Display ausgeschaltet werden. Dies erfolgt durch das Senden von 0x08 (vgl. Datenblatt). // Das Senden erfolgt analog zu der obigen Erklärung (dort war es 0x28 für den 4-Bit-Modus). // Danach muss das Display gelöscht werden. Hierzu muss 0x01 gesendet werden (vgl. Datenblatt). // Zu guter letzt muss noch der Start-Modus (entry mode) definiert werden. // Hier soll das Display einfach aktiviert und der Cursor deaktiviert werden. Dies erfolgt durch Senden von 0x0C. //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. (s.u.) ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// delay(100); //0x08 <- Als nächstes soll das Display ausgeschaltet werden. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0b0000 (0) von 8 LCD_DATA0_PORT &= ~_BV(DB0); //0 // macht insgesamt 0 + 8 = 8 -> 0x08 toggle_e(); LCD_DATA3_PORT = _BV(DB3); //1 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0bxxxx1000 (8) von 8 LCD_DATA0_PORT &= ~_BV(DB0); //0 toggle_e(); //Dann werden alle Datenpins wieder auf logisch '0' gesetzt. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 LCD_DATA0_PORT &= ~_BV(DB0); //0 ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// delay(100); //Danach muss das Display gelöscht werden. Hierzu muss 0x01 gesendet werden //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0b0000 (0) von 1 LCD_DATA0_PORT &= ~_BV(DB0); //0 // macht insgesamt 0 + 1 = 1 -> 0x01 toggle_e(); LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0bxxxx0001 (1) von 1 LCD_DATA0_PORT = _BV(DB0); //1 toggle_e(); //Dann werden alle Datenpins wieder auf logisch '0' gesetzt. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 LCD_DATA0_PORT &= ~_BV(DB0); //0 //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// delay(100); //Hier soll das Display einfach aktiviert und der Cursor deaktiviert werden. Dies erfolgt durch Senden von 0x0C. //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0b0000 (0) von 12 LCD_DATA0_PORT &= ~_BV(DB0); //0 // macht insgesamt 0 + 12 = 12 -> 0x0c toggle_e(); LCD_DATA3_PORT = _BV(DB3); //0 LCD_DATA2_PORT = _BV(DB2); //1 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble 0bxxxx1100 (12) von 12 LCD_DATA0_PORT &= ~_BV(DB0); //0 toggle_e(); //Dann werden alle Datenpins wieder auf logisch '0' gesetzt. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 LCD_DATA0_PORT &= ~_BV(DB0); //0 delay(100); /////////////////////////////////////////////////////////////// //////////////////////INITIALIESIERUNG ABGESCHLOSSEN/////////// /////////////////////////////////////////////////////////////// //Das Schreiben von Daten auf dem Display funktioniert mit //den bereits oben angeführten Befehlen. RS muss auf H-Pegel sein, R/W auf Low. LCD_RS_PORT |= _BV(LCD_RS); LCD_RW_PORT |= _BV(LCD_RW); //0010 0001=! delay(100); //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT = _BV(DB1); //1 -> high nibble LCD_DATA0_PORT &= ~_BV(DB0); //0 toggle_e(); LCD_DATA3_PORT = _BV(DB3); //1 LCD_DATA2_PORT &= ~_BV(DB2); //0 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> high nibble LCD_DATA0_PORT &= ~_BV(DB0); //0 toggle_e(); }
Hat jemand ne idee was da nicht stimmt?.....
Gruß
Scrat1







Zitieren
Lesezeichen