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:
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
#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
}
leider funktioniert die Busi funktion noch nicht. Naja das werd ich noch hinbekommen, aber wenn jemand schon den Fehler sieht, kann er ihn ruhig sagen 
Also Danke nochmals für eure Hilfe!!
Gruß
Scrat1
Lesezeichen