Also habs jetzt geschafft 2 Sachen waren zu machen:
1. 0x28 = 40 = 0b0010 1000 und nicht 0b0010 0100 !!
2. Entry Mode musste noch gesetzt werden 0b0000 0111
jetzt sieht der Code so aus:
leider funktioniert die Busi funktion noch nicht. Naja das werd ich noch hinbekommen, aber wenn jemand schon den Fehler sieht, kann er ihn ruhig sagenCode:#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 #define Ende all_low(); //WELCHES NUN all_low MEINS all_high PETER FLEURY'S #define busy delay(500); //busi(); void toggle_e(void) { LCD_E_PORT |= (1 << LCD_E); //LCD_E_PORT |= _BV(LCD_E); asm volatile ("rjmp 1f\n 1:"); //warte 500ns 0,543 us LCD_E_PORT &=~(1 << LCD_E); //LCD_E_PORT &= ~_BV(LCD_E); } void all_high(void) { LCD_DATA0_PORT |= _BV(DB0); LCD_DATA1_PORT |= _BV(DB1); LCD_DATA2_PORT |= _BV(DB2); LCD_DATA3_PORT |= _BV(DB3); } void all_low(void) { LCD_DATA3_PORT &= ~_BV(DB3); LCD_DATA2_PORT &= ~_BV(DB2); LCD_DATA1_PORT &= ~_BV(DB1); LCD_DATA0_PORT &= ~_BV(DB0); } void delay(unsigned long count) { long i; for(i=0;count>i;i++) { 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 busi(void) { //char dataH; //char dataL; LCD_RW_PORT |= _BV(LCD_RW); LCD_RS_PORT &= ~_BV(LCD_RS); //DDRD &= ~(1 << LCD_E); 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)) {asm volatile ("nop");} // solange warten, bis DB3 (busyFlag) auf 0 LCD_E_PORT &= ~_BV(LCD_E); // LCD_E auf low DDRD = 0xFF; //und alles auf Ausgang natürlich } int main(void) { /* write data (RS=1, RW=0) */ /* write instruction (RS=0, RW=0) */ DDRD = 0xFF; DDRB = 0xFF; delay(20000); //warte 20 ms (20000us) all_low(); LCD_DATA1_PORT |= (1<<DB1); LCD_DATA0_PORT |= (1<<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); // des muss genommen werden, weil ich ja 0b0010 0000 haben will und oben ist 0b0011 0000 also DB0 löschen!!!! 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. 0x28 = Function set 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 8 + 32 = 40 -> 0x28 toggle_e(); LCD_DATA3_PORT |= _BV(DB3); LCD_DATA2_PORT &= ~_BV(DB2); 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. Ende // 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.) ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// 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 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(); Ende // jetzt kommt lcd_clrscr und set_entry_mode ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// 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 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(); Ende // was soll des sein ? 0b0000 0110 ?? aha des isch set entry mode DB1 und DB2 //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// 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 delay(100); //Hier soll das Display set entry mode DB1 und DB2 //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); //1 -> high nibble 0bxxxx1100 (12) von 12 LCD_DATA0_PORT |= _BV(DB0); //1 <- nach datasheet kann aber auch 0 sein toggle_e(); Ende //////////////////////////////////////////////////////////// ////////////////*/////////////////////////////////////////// //////////////////////////////////////////////////////////// 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 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); //1 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(); Ende 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 &= ~(1 << LCD_RW); // LCD_RW_PORT |= _BV(LCD_RW); // ES WIRD Hi ausgegeben!! //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT |= _BV(DB2); //1 LCD_DATA1_PORT &= ~_BV(DB1); //0 -> 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(); busy //Die beiden Nibble werden nun hintereinander an das LCD gesendet, das obere zuerst. LCD_DATA3_PORT &= ~_BV(DB3); //0 LCD_DATA2_PORT |= _BV(DB2); //1 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); //1 toggle_e(); busy }![]()
Also Danke nochmals für eure Hilfe!!
Gruß
Scrat1







Zitieren

Lesezeichen