CsMTEch
18.06.2014, 15:40
Hallo, ich bin es nochmal.
Ich wollte nun ein LCD ansteuern, die Initialisierung scheint auch geklappt zu haben, da das Display gelöscht wird und es scheinbar auch auf zweizeilig umgestellt wird. Demnach müsste ja alles richtig angeschlossen sein.
Nun wird aber aus "H a l l o W e l t" "J ° █ █ █ █ █ █ █ █". Die Anzahl der Zeichen stimmt also noch, aber es ist halt Humbug was da angezeigt wird...
Könnte das evtl am Code liegen?
Als erstes muss meines Wissens nach ja das höhere Nibble übertragen werden. Also selektiere ich erst nur die oberen 4 Bits (Bit 4-7). Das soll mit dieser Funktion geschehen:
int HigherNibble(char Char)
{
LCD_Port &= 0b00001111; //Alle Ausgänge für die Datenleitungen werden auf Low gesetzt
int Maske = Char;
Maske &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)); //Die unteren Datenleitungen werden in der Maske auf 0 gesetzt, damit sie nachher gleich bleiben
return Maske;
}
Nun muss das niedrigere Nibble übertragen werden, allerdings auch an den uC Pins PB.4 - PB.7. Also habe ich eine Funktion geschrieben, die die Nibbles vertauscht (in Assembler wäre das doch eigentlich "swap" oder?).
int LowerNibble(char Char)
{
int Counter = 0;
int Maske = 0;
int Compare = 0;
int Potenz;
LCD_Port &= 0b00001111; //Alle Ausgänge für die Datenleitungen werden auf Low gesetzt
while (Counter <= 3) // Sorgt für die 4 Durchgänge
{
Compare = Char; //Compare wird mit Char "gefüllt" um nach einem Durchlauf, diese Variable wieder auf den Anfangszustand zu setzen
Potenz = Potenzieren(2, Counter); //Durch das Potenzieren ereicht man die Masken, wo jeweils ein Bit auf 1 ist
Compare &= Potenz; //Selektiert einen Bit von Compare also 0, 1, 2 oder 3
if(Compare != 0)
{
Maske |= (1 << (Counter+4)); //Wenn dieser Bit an ist schreibe eine 1 an die entsprechende Stelle des höheren Nibbles
}
Counter++;
}
Maske &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)); //Die unteren Datenleitungen werden in der Maske auf 0 gesetzt, damit sie nachher gleich bleiben
return Maske;
}
Dazu gehört noch die Funktion Potenzieren;
int Potenzieren(int Basis, int Exponent)
{
int Ergebnis = 1;
while(Exponent>0)
{
Ergebnis = Ergebnis*Basis;
Exponent--;
}
return Ergebnis;
}
Die Nibbles werden dann nacheinander in der Funktion LCD_Char übertragen:
void LCD_Char(char Char)
{
LCD_Port |= (1<<2); //RS = 0
LCD_Port |= LowerNibble(Char);
LCD_Enable(); //Setzt E kurz auf ein 1 dann wieder auf 0
_delay_ms(20);
LCD_Port |= HigherNibble(Char);
LCD_Enable(); //Setzt E kurz auf ein 1 dann wieder auf 0
_delay_ms(20);
}
Weiß jemand wo da ein Fehler sein könnte oder woran es noch liegen könnte? ._.
Und noch was... :
Es gibt ja schon viele Threads zu Problemen mit _delay_ms(), aber zu meinem habe ich noch keinen gefunden.
Ich benutze einen ATMega32 der ja eigentlich eine Frequenz von 16 mHz besitzt. Dieses lege ich mit #define F_CPU 16000000UL fest. Nun dauert _delay_ms(1000) aber um das achtfache zu langsam. Schreibe ich _delay_ms(125) oder achtel ich Frequenz (#define F_CPU 2000000UL) dauert die Wartezeit 1 Sekunde (nicht genau gemessen). Hätte da jemand eine Lösung für?
Vielen Dank im Voraus und ich hoffe auf baldige Antwort!
LG Ulf
Ich wollte nun ein LCD ansteuern, die Initialisierung scheint auch geklappt zu haben, da das Display gelöscht wird und es scheinbar auch auf zweizeilig umgestellt wird. Demnach müsste ja alles richtig angeschlossen sein.
Nun wird aber aus "H a l l o W e l t" "J ° █ █ █ █ █ █ █ █". Die Anzahl der Zeichen stimmt also noch, aber es ist halt Humbug was da angezeigt wird...
Könnte das evtl am Code liegen?
Als erstes muss meines Wissens nach ja das höhere Nibble übertragen werden. Also selektiere ich erst nur die oberen 4 Bits (Bit 4-7). Das soll mit dieser Funktion geschehen:
int HigherNibble(char Char)
{
LCD_Port &= 0b00001111; //Alle Ausgänge für die Datenleitungen werden auf Low gesetzt
int Maske = Char;
Maske &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)); //Die unteren Datenleitungen werden in der Maske auf 0 gesetzt, damit sie nachher gleich bleiben
return Maske;
}
Nun muss das niedrigere Nibble übertragen werden, allerdings auch an den uC Pins PB.4 - PB.7. Also habe ich eine Funktion geschrieben, die die Nibbles vertauscht (in Assembler wäre das doch eigentlich "swap" oder?).
int LowerNibble(char Char)
{
int Counter = 0;
int Maske = 0;
int Compare = 0;
int Potenz;
LCD_Port &= 0b00001111; //Alle Ausgänge für die Datenleitungen werden auf Low gesetzt
while (Counter <= 3) // Sorgt für die 4 Durchgänge
{
Compare = Char; //Compare wird mit Char "gefüllt" um nach einem Durchlauf, diese Variable wieder auf den Anfangszustand zu setzen
Potenz = Potenzieren(2, Counter); //Durch das Potenzieren ereicht man die Masken, wo jeweils ein Bit auf 1 ist
Compare &= Potenz; //Selektiert einen Bit von Compare also 0, 1, 2 oder 3
if(Compare != 0)
{
Maske |= (1 << (Counter+4)); //Wenn dieser Bit an ist schreibe eine 1 an die entsprechende Stelle des höheren Nibbles
}
Counter++;
}
Maske &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)); //Die unteren Datenleitungen werden in der Maske auf 0 gesetzt, damit sie nachher gleich bleiben
return Maske;
}
Dazu gehört noch die Funktion Potenzieren;
int Potenzieren(int Basis, int Exponent)
{
int Ergebnis = 1;
while(Exponent>0)
{
Ergebnis = Ergebnis*Basis;
Exponent--;
}
return Ergebnis;
}
Die Nibbles werden dann nacheinander in der Funktion LCD_Char übertragen:
void LCD_Char(char Char)
{
LCD_Port |= (1<<2); //RS = 0
LCD_Port |= LowerNibble(Char);
LCD_Enable(); //Setzt E kurz auf ein 1 dann wieder auf 0
_delay_ms(20);
LCD_Port |= HigherNibble(Char);
LCD_Enable(); //Setzt E kurz auf ein 1 dann wieder auf 0
_delay_ms(20);
}
Weiß jemand wo da ein Fehler sein könnte oder woran es noch liegen könnte? ._.
Und noch was... :
Es gibt ja schon viele Threads zu Problemen mit _delay_ms(), aber zu meinem habe ich noch keinen gefunden.
Ich benutze einen ATMega32 der ja eigentlich eine Frequenz von 16 mHz besitzt. Dieses lege ich mit #define F_CPU 16000000UL fest. Nun dauert _delay_ms(1000) aber um das achtfache zu langsam. Schreibe ich _delay_ms(125) oder achtel ich Frequenz (#define F_CPU 2000000UL) dauert die Wartezeit 1 Sekunde (nicht genau gemessen). Hätte da jemand eine Lösung für?
Vielen Dank im Voraus und ich hoffe auf baldige Antwort!
LG Ulf