- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 5 von 5

Thema: LCD - Char übersenden ; Probleme mit _delay_ms();

  1. #1
    Benutzer Stammmitglied Avatar von CsMTEch
    Registriert seit
    01.05.2013
    Ort
    bei Aurich (Niedersachsen)
    Beiträge
    73

    Ausrufezeichen LCD - Char übersenden ; Probleme mit _delay_ms();

    Anzeige

    Powerstation Test
    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:

    Code:
    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?).

    Code:
    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;
    Code:
    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:
    Code:
    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

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Ob dein Mega32 mit 16MHz läuft oder mit anderer Frequenz, legst du nicht mit #define F_CPU 16000000UL fest. Hier teilst du die Frequenz nur deinem Programm mit.
    Für 16MHz brauchst du einen Quarz oder Quarzoszillator und die entsprechenden Einstellungen der Fuses.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Benutzer Stammmitglied Avatar von CsMTEch
    Registriert seit
    01.05.2013
    Ort
    bei Aurich (Niedersachsen)
    Beiträge
    73
    Zitat Zitat von Hubert.G Beitrag anzeigen
    Ob dein Mega32 mit 16MHz läuft oder mit anderer Frequenz, legst du nicht mit #define F_CPU 16000000UL fest. Hier teilst du die Frequenz nur deinem Programm mit.
    Für 16MHz brauchst du einen Quarz oder Quarzoszillator und die entsprechenden Einstellungen der Fuses.
    OK, das erklärt schon mal das eine Problem

    Vielen Dank!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    18.05.2013
    Beiträge
    18
    Irgendwie check ich nicht was du da machen willst.
    *Wenn du mit chars arbeitest, dann arbeite auch mit chars und mische nicht int und char.
    *Die delays kommen mir teilweise irgendwie (zu) hoch vor.
    *Verarbeite deinen char in einer Funktion, und greife auf den port in einer anderen zu. So verliert man nicht die Übersicht. Bei dir scheint das alles irgendwie vermischt zu sein und es ist nicht ganz klar was du wo machst.

    Bei mir schaut das senden eines char an einen HD44780 im 4 bit Modus so aus:

    Code:
    #define LCD_DATA_PORT PORTB
    #define LCD_DB7 PB5
    #define LCD_DB6 PB4
    #define LCD_DB5 PB3
    #define LCD_DB4 PB2
    #define LCD_E_PORT PORTB
    #define LCD_E PB1
    #define LCD_RS_PORT PORTB
    #define LCD_RS PB0
    ....
    Code:
    void lcdShowChar(unsigned char show_ch)
    {
      LCD_RS_PORT |= (1 << LCD_RS);
      lcdSendNibble(show_ch >> 4);
      lcdSendNibble(show_ch);
      _delay_us(40);
    }
    
    void lcdSendNibble(unsigned char nibble)
    {
      LCD_DATA_PORT &= ~(1 << LCD_E) & ~(1 << LCD_DB4) & ~(1 << LCD_DB5)
      & ~(1 << LCD_DB6) & ~(1 << LCD_DB7);
    
      LCD_E_PORT |= (1 << LCD_E);
      LCD_DATA_PORT |= ((nibble & 0x01) << LCD_DB4);
      nibble >>= 1;
      LCD_DATA_PORT |= ((nibble & 0x01) << LCD_DB5);
      nibble >>= 1;
      LCD_DATA_PORT |= ((nibble & 0x01) << LCD_DB6);
      nibble >>= 1;
      LCD_DATA_PORT |= ((nibble & 0x01) << LCD_DB7);
      LCD_E_PORT &= ~(1 << LCD_E);
    }
    Vielleicht hilft dir das etwas. Geht aber sicher auch schöner und man könnte den PORT auch auf einmal mit einer Maske beschreiben als den char jedesmal um 1 zu verschieben. Wenn ich das nächste mal ein lcd brauche werde ich das auch wahrscheinlich dahingehend abändern.
    Geändert von Siad (19.06.2014 um 06:08 Uhr)

  5. #5
    Benutzer Stammmitglied Avatar von CsMTEch
    Registriert seit
    01.05.2013
    Ort
    bei Aurich (Niedersachsen)
    Beiträge
    73
    Ich hab jetzt den Tipp, bei den Chars zu bleiben, ausprobiert und siehe da, alles funktioniert jetzt noch LCD_String(); schreiben und das LCD ist abgehakt

    Vielen Dank

    Ulf

Ähnliche Themen

  1. char sprintf Probleme
    Von I_-_I---c im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 10.11.2013, 13:36
  2. Probleme mit LCD (HD44780) Wie sezt man einen ascii-char auf cursor pos ?
    Von fugitivus im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 23.04.2011, 11:14
  3. Probleme über Variabel-Addressierung auf Flash-Char
    Von Nicy im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 12.01.2009, 18:17
  4. RS232 P. Fleury Char und String Probleme mal wieder
    Von PCMan im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 31.10.2007, 15:52
  5. Laufschrift aktualisieren, Probleme mit char*
    Von PCMan im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 20.07.2007, 13:01

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test