Forum: Mikrocontroller und Digitale Elektronik Nicht alle selbstdefinierten Zeichen gehen.


von Tobi (Gast)


Angehängte Dateien:

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

von Falk B. (falk)


Lesenswert?

@  Tobi (Gast)

>Ich denke, der Adressbereich ist 0x40 + 8 für jedes weitere Zeichen.
>Oder ?

Ja.

Du musst aufpassen, deine Funktion funktioniert nur, wenn Auto Increment 
im LCD aktiv ist.

MFG
Falk

von Tobi (Gast)


Lesenswert?

Hallo Falk,

hab ich nicht die Auto Inkrement Funktion eingestellt ?
In der Init Sequenz steht #06 drin...

Viele Grüße
Tobi

von Tobi (Gast)


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.

von Tobi (Gast)


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

von holger (Gast)


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

}

von spess53 (Gast)


Lesenswert?

Hi

>Bin ich blöd oder blind ?

Das musst du entscheiden. Aber es sieht so aus, als ob du versuchst 9 
(0...8) eigene Zeichen in 8 Speicherplätze zu quetschen.

MfG Spess

von Tobi (Gast)


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.

von Karl H. (kbuchegg)


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?

von Tobi (Gast)


Angehängte Dateien:

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.

von Tobi (Gast)


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.

von spess53 (Gast)


Lesenswert?

Hi

>Ich glaub, ich hänge mal den ganzen aktuellen Code an.
>Da hab ich die letzten Tage so oft dran was verändert.

Warum postest du nicht C-File? Dann gibt es auch eine Code-Ansicht.

MfG Spess

von Tobi (Gast)


Lesenswert?

Timing ? Gut möglich, an welcher Stelle ?
Nach der Intialisierung ?
Zwichen dem CGRAM-Beschreiben ? (Hab ich schonmal 100ms probiert, ging 
net)

von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Gute Idee.
Stirnpatsch

von Falk B. (falk)


Lesenswert?

@  Tobi (Gast)

>Ich glaub, ich hänge mal den ganzen aktuellen Code an.

Und warum hängst du den nicht DIREKT an, als .c Datei? Dann würde er 
auch schon mit Syntax Highlighting dargestellt werden.

Siehe Netiquette.

von Tobi (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.

von holger (Gast)


Angehängte Dateien:

Lesenswert?

Nimm das.

von Tobi (Gast)


Lesenswert?

Gute Idee !
Habs gleich mal ausprobiert...
Leider negativ.
Weder 10ms, noch 50ms.
Sowohl nach dem Commando-Aufruf für die Adresse.
Als auch nach jedem Byte.

von Tobi (Gast)


Lesenswert?

Holger, irgendwie blick ich da nicht durch. Dein Script ist so 
allgemeingültig mit so vielen Definitionsvarianten....

von Tobi (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.