Nicht alle selbstdefinierten Zeichen gehen.

Gast #2229410
Lesenswert?

Hallo,

jetzt hab ich das Problemchen mit der Initialisierung von dem DOGM081 
LCD gelöst, schon kommt das Nächste.

Die Routine für die selbstdefinierten 8 Zeichen ist aus dem Tutorial.
Aber es scheint, als wenn ich mehr als 5 Zeichen definiere, dann geht 
das schief. Beim 6. Zeichen wird das erste korrupt. Beim 7. Zeichen 
sinds dann zwei. Und bei allen 8 sinds drei.

Hat jemand eine Idee ?
Ich denke, der Adressbereich ist 0x40 + 8 für jedes weitere Zeichen.
Oder ?

In dem PDF vom DOGM081 finde ich dazu leider nichts.

Viele Grüße
Tobi
Angehängte Dateien:
Gast #2230872
Lesenswert?

Was ich auch sehr seltsam finde.
Ich habe mal testweise nach der Initialisierung alle 8 Zeichen 
dargestellt.
Dabei gehen die Zeichen 2 und 3 nicht.

An einem späteren Zeitpunkt im Programm rufe ich erneut die Routine 
LCD_Data(... auf und dann gehen die Zeichen 3,4,5,6 und 7 nicht richtig.
Zeichen 3 ist leer.
Zeichen 4 ist wie Zeichen 2 um eine Pixel-Linie nach oben verschoben.
Zeichen 5 ist fast wie Zeichen 1, um eine Pixel-Linie nach oben 
verschoben.
Und Zeichen 7 ist auch fast wie Zeichen 7 sein soll, nur um eine 
Pixel-Linie nach oben verschoben...
Zeichen 6 ist kompletter Datenmüll.

Ich versteh das nicht.
Gast #2233199
Lesenswert?

Niemand 'ne Idee ?

Ich hab mal ein anderes (16x2) Display versucht. Gleiche Symptomatik.
Liegt also nicht am DOGM081.

Auch wenn ich die Arrays mit den Benutzerdefinitionen tausche ändert 
sich nichts. Das "fehlerhafte" Bild wandert mit.
Aber in der Benutzerdefinition finde ich keinen Fehler.

Sobald ich nicht alle 8 Zeichen ins CGRAM lade gehts... (also die 
restlichen 7). Dabei ist es egal, welches Zeichen ich nicht lade...

Ich verstehs nicht.

Bin ich blöd oder blind ?

Viele Grüße
Tobi
Gast #2233206
Lesenswert?

Versuch das mal:

void lcd_generatechar(uint8_t code, const uint8_t *data)
{
    // Startposition des Zeichens einstellen
    lcd_command(LCD_SET_CGADR|(code<<3));

    // Bitmuster übertragen
    for (uint8_t i=0; i<8; i++)
    {
        lcd_data(data[i]);
    }

 lcd_command(0x80); //DD_RAM Adresse 0 setzen, besser ist das

}
Gast #2233222
Lesenswert?

Hm.
Meine Sequenz schaut grad so aus:

void lcd_generatechar(uint8_t code, const uint8_t *data)
{
    // Startposition des Zeichens einstellen
    lcd_command(0x40|(code<<3));

    // Bitmuster übertragen
    for (uint8_t i=0; i<8; i++)
    {
        lcd_data(data[i]);
    }
  lcd_command(0x80);
}

Also eigentlich quasi identisch.
Ich habs auch schonmal versucht die Adressen einzeln zu schreiben.
Also 40,48,50,58,60,68,70 und 78.

Spess, der Gedanke kam mir auch. Irgendwie schauts so aus.
Aber ich versteh nicht wo ich das machen würde.
Für mich siehts so aus, als ob ich nur von 0 bis 7 zählen würde.
#2233234
Lesenswert?

Tobi schrieb:

> Spess, der Gedanke kam mir auch. Irgendwie schauts so aus.
> Aber ich versteh nicht wo ich das machen würde.


  lcd_data(LCD_GC_CHAR0);
  lcd_data(LCD_GC_CHAR1);
  lcd_data(LCD_GC_CHAR2);
  lcd_data(LCD_GC_CHAR3);
  lcd_data(LCD_GC_CHAR4);
  lcd_data(LCD_GC_CHAR5);
  lcd_data(LCD_GC_CHAR6);
  lcd_data(LCD_GC_CHAR7);
  lcd_data(LCD_GC_CHAR8);

Zähl nach: Sind 9 Stück.

(WIe du das durch den Compiler gebracht hast, weiß ich allerdings 
nicht.)

Drum wäre es eine extrem gute Idee, hier
1
void lcd_generatechar(uint8_t code, const uint8_t *data)
2
{
3
    // Startposition des Zeichens einstellen
4
    lcd_command(0x40|(code<<3));
5

6
    // Bitmuster übertragen
7
    for (uint8_t i=0; i<8; i++)
8
    {
9
        lcd_data(data[i]);
10
    }
11
  lcd_command(0x80);
12
}

die übergebene code Nummer sicherheitshalber noch auf 0 bis 7 
einzuschränken.
1
void lcd_generatechar(uint8_t code, const uint8_t *data)
2
{
3
    // Startposition des Zeichens einstellen
4
    lcd_command( 0x40 | ((code & 0x07) << 3) );

das schützt schon mal vor falschen Argumenten.


Edit: flascher Alarm. Das ist ja nur der Aufruf der Zeichen. Die 
Definition sieht ok aus.

Hmm. Timingproblem? Dem LCD nach der Definition ein wenig Zeit geben?
Gast #2233243
Lesenswert?

Öha. Gut das kann sein.

Im aktuellen Code steht inzwischen:

lcd_generatechar(1, chrdata0);
lcd_generatechar(2, chrdata2);
lcd_generatechar(3, chrdata3);
lcd_generatechar(4, chrdata4);
lcd_generatechar(5, chrdata5);
lcd_generatechar(6, chrdata6);
lcd_generatechar(7, chrdata7);
lcd_generatechar(0, chrdata1);

Ich glaub, ich hänge mal den ganzen aktuellen Code an.
Da hab ich die letzten Tage so oft dran was verändert.
Angehängte Dateien:
Gast #2233248
Lesenswert?

Hab die Zeile mal noch implementiert.
Aber es ändert nichts.

Ich hab auch nochmal in den originalen Code geschaut.
Da wurden nur 8 Zeichen ins CGRAM geschrieben.

Es wurde ein LCD_data für das 9. Zeichen angefragt, das stimmt.
Aber das ist schon lang raus.
#2233268
Lesenswert?

Tobi schrieb:
> Sorry. Ich werde es mir in Zukunft merken.
>
> 100ms Pause nach der Initialisierung und vor dem ersten Schreiben eines
> Arrays in das CGRAM ging auch nicht.

Dazwischen!
Nach jeden Byte einfach mal, Hausnummer, 10 Millisekunden warten.
1
void lcd_generatechar(uint8_t code, const uint8_t *data)
2
{
3
    // Startposition des Zeichens einstellen
4
    lcd_command(0x40|(code<<3));
5
    _delay_ms( 10 );
6

7
    // Bitmuster übertragen
8
    for (uint8_t i=0; i<8; i++)
9
    {
10
        lcd_data(data[i]);
11
        _delay_ms( 10 );
12
    }
13
    lcd_command(0x80);
14
    _delay_ms( 10 );
15
}

Ist ein Schuss ins Blaue. Zugegeben.
Gast #2238109
Lesenswert?

Hallo nochmal,

kann ich hier auch Teile eines C-Programms attachen ? Ich möchte das 
Programm
auf das Wesentliche reduzieren. Und aber der Netiquette entsprechend 
keine Text-Files anhängen.

Es scheint wohl so, daß nicht (nur?) die LCD Ansteuerungs Routine das 
Problem ist.

In meinem Programm wird ein PGA Lautstärke-Steller angesteuert.
Die Lautstärke-Werte werden durch einen Drehinkrementalgeber ermittelt.
Also gibt es irgendwo eine Schleife für die Dekodierung des Gray-Codes.
Das funktioniert auch.
Wenn ich aber z.B. in die Schleife eine zusätzliche Abfrage des B-Portes
einfüge, an dem der Taster für das Muting angeschlossen ist, ändern sich
die Zeichen, die nicht gehen.

Weiterhin habe ich einen Zähler, der die Gray-Code-Schleife hochzählt.
Erreicht er einen Wert von 150.000, dann wird das Display mit 
Leerzeichen
geblanked.
Diese Abfrage führt ebenfalls dazu, daß sich andere Zeichen nicht mehr
richtig darstellen lassen.

Wenn ich diese beiden Teile rausnehme, geht immerhin nur noch die 2 
nicht mehr.

Es scheint also nicht direkt mit den LCD-Routinen zu tun zu haben.
Irgendwo pfuscht das Programm da an anderer Stelle rein.

Der ermittelte Lautstärkewert steht am Ende in der Variable "zaehler" 
und
wird an die LCD-Routine und den PGA übergeben.
Ich dachte auch daran, daß diese Variable dann nicht mehr geht.
Aber das stimmt nicht.
Auch wenn ich da fixe Werte reinschreibe, hängt die Ausgabe davon ab,
ob in der Gray-Code-Schleife die besagten Teile drin sind, oder nicht...

Ich versteh das nicht.

Viele Grüße
Tobi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren