Forum: Mikrocontroller und Digitale Elektronik OLED Verständnisproblem


von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Community,

ich habe ein Problem mit meinem OLED-Display.
Ich versuche seit Tagen es vernünftig zum Laufen zu bringen.
Programmieren tue ich es in C mit dem AVR-Studio 6.
Laufen soll es auf einem Atmega8.
Es handelt sich um ein OLED von electronic Assembly (Typ EA W082-XLG)

Was funktioniert schon?
-Ich bekomme es Initialisiert. Alles okay.
-Ich kann auch was ausgeben. Läuft :-)
-Cursor lässt sich an gewünschte Position verschieben (Auch in 2. Zeile)

Was ist mein Problem?
- wenn ich dem Cursor verschoben habe, lässt sich nix mehr schreiben
egal in welcher Zeile und Position...

Habt ihr da eine Idee?

Wenn das Programm (siehe Anhang) läuft, sieht die Ausgabe am Display so 
aus:
           ##########
           #12341234#
           #12341234#
           ##########

Der Cursor rutscht irgendwann in die Zweite Zeile und schreibt auch 
diese voll. Es scheint also richtig Initialisiert zu sein. Ich sehe ihn 
immer durchwandern und Stellen überschreiben.

Sorry schonmal für die eventuell unsaubere Programmierung.
Bin noch ziemlicher Neuling, was die µC-Welt angeht.

: Verschoben durch Moderator
von Martin B. (drehzahlloeffel)


Lesenswert?

Nachdem ich mich jetzt registriert habe, melde ich mich nochmal dazu.

Ich habe den Fehler jetzt lokalisiert, konnte ihn aber noch nicht 
endgültig beheben.

Es liegt an meiner Busy-Flag Abfrage. Da kommt er nicht mehr raus und 
bleibt hängen.

Habe das Programm modifiziert und es läuft prima.
Aber eben nur, wenn ich die Abfrage komplett weg lasse und überall kurze 
Verzögerungen im µs-Bereich einbaue.

So die optimale Lösung ist es natürlich nicht.

hier mal der Code-Schnippel, der nicht funktioniert:
1
uint8_t BusyZustand = 0b00000000;
2
uint8_t BusyHIGH =0b10000000;
3
uint8_t BusyErgebnis = 0b10000000;
4
5
//-----------------------------------
6
//----- Busy zyklisch checken
7
//-----------------------------------
8
void BusyAbfrage(void)
9
{
10
  BusyZustand = 0b00000000;
11
  BusyHIGH =0b10000000;
12
  BusyErgebnis = 0b10000000;
13
  
14
  while(BusyErgebnis>0)
15
  {
16
  DDRD = 0x00;
17
  DDRB |= ( 1 << PB0 )|( 1 << PB1 );  // PB0, PB1 als Ausgang setzen
18
  PORTB &= ~(1<<PB0);               //löschen (PBo auf NULL setzen)
19
  PORTB |= (1<<PB1);                //PB1 auf EINS setzen
20
                                      //RS = 0
21
                                      //RW = 1
22
  BusyZustand=PIND;
23
  wartemikrosekunden(5);
24
  BusyErgebnis= BusyZustand & BusyHIGH;
25
  }
26
}

In jedem Programmteil, wo ich dann neue Befehle ans OLED sende, wollte 
ich dann zuerst
1
BusyAbfrage();
durchführen. Und das funktioniert leider nicht.

Habt ihr eine Idee, woran es liegen könnte?

Grüße

von Stefan E. (sternst)


Lesenswert?

Martin B. schrieb:
> hier mal der Code-Schnippel, der nicht funktioniert:

Wo sind da die EN-Pulse?

von Martin B. (drehzahlloeffel)


Lesenswert?

Ein guter Einwand :-)

Habe es gerade ausprobiert... bringt aber keine Besserung.
Getestet mit 2 und 3 EN-Pulsen.

So habe ich es probiert:
1
void BusyAbfrage(void)
2
{
3
BusyZustand = 0b00000000;
4
BusyHIGH =0b10000000;
5
BusyErgebnis = 0b10000000;
6
  
7
while(BusyErgebnis>0)
8
{
9
  DDRD = 0x00;
10
  DDRB |= ( 1 << PB0 )|( 1 << PB1 );   // PB0, PB1 als Ausgang setzen
11
  PORTB &= ~(1<<PB0);   //löschen (PBo auf NULL setzen)
12
  PORTB |= (1<<PB1);    //PB1 auf EINS setzen
13
  //RS = 0
14
  //RW = 1
15
  wartemikrosekunden(5);
16
  PORTB |= (1<<PB2);    // EN = 1
17
  wartemikrosekunden(5);
18
  PORTB &= ~(1<<PB2);    // EN = 0
19
  wartemikrosekunden(5);
20
  PORTB |= (1<<PB2);    // EN = 1
21
  wartemikrosekunden(5);
22
  PORTB &= ~(1<<PB2);    // EN = 0
23
  wartemikrosekunden(5);
24
  PORTB |= (1<<PB2);    // EN = 1
25
  wartemikrosekunden(5);
26
  PORTB &= ~(1<<PB2);    // EN = 0
27
  wartemikrosekunden(5);
28
  
29
  BusyZustand=PIND;
30
  wartemikrosekunden(5);
31
    
32
  BusyErgebnis= BusyZustand & BusyHIGH;
33
  }
34
}

von Stefan E. (sternst)


Lesenswert?

Martin B. schrieb:
> So habe ich es probiert:

Nö. Du setzt EN auf 1, liest das Busy-Flag, setzt EN wieder auf 0. Und 
das wiederholst du so lange wie das Busy-Flag 1 ist.

von Martin B. (drehzahlloeffel)


Lesenswert?

GENIAL!!!

Jetzt läuft es. Vielen Dank!!
Bei mir reichen zwei Impulse. Mit einem ging es nicht.

Ich habe es mir doch gedacht, da ist nur ein einfacher Denkfehler drin.

Danke Stefan, hast mir den Abend gerettet!

Sieht jetzt so aus:
1
void BusyAbfrage(void)
2
{
3
  BusyZustand = 0b00000000;
4
  BusyHIGH =0b10000000;
5
  BusyErgebnis = 0b10000000;
6
  
7
  while(BusyErgebnis>0)
8
  {
9
    DDRD = 0x00;
10
    DDRB |= ( 1 << PB0 )|( 1 << PB1 );   // PB0, PB1 als Ausgang setzen
11
    PORTB &= ~(1<<PB0);                  //löschen (PBo auf NULL setzen)
12
    PORTB |= (1<<PB1);                   //PB1 auf EINS setzen
13
                                         //RS = 0
14
                                         //RW = 1
15
    wartemikrosekunden(5);
16
    
17
    PORTB |= (1<<PB2);                   // EN = 1
18
    wartemikrosekunden(5);               // warte 5µs Ausgang stabilisieren
19
    BusyZustand=PIND;                    //Busy-Flag abholen
20
    PORTB &= ~(1<<PB2);                  // EN = 0
21
    
22
    PORTB |= (1<<PB2);                   // EN = 1
23
    wartemikrosekunden(5);               // warte 5µs Ausgang stabilisieren
24
    BusyZustand=PIND;                    //Busy-Flag abholen
25
    PORTB &= ~(1<<PB2);                  // EN = 0
26
      
27
      
28
    BusyErgebnis= BusyZustand & BusyHIGH;
29
  }
30
}

von holger (Gast)


Lesenswert?

Schon mal nachgemessen ob der Busy Check sich überhaupt lohnt?
Ich finde die Delay Methode besser. Dann läuft die Schaltung
auch ohne Display wenn es sein muss;)

von Martin B. (drehzahlloeffel)


Lesenswert?

Bin mir nicht sicher, wie ich das beantworten soll....

Mit der Delay-Methode habe ich stabilen Betrieb hinbekommen, indem ich 
nach jedem Befehl 5µs gewartet habe. Und wirklich nach Jedem. (Befehl 
senden, Zeichen/Zeichenkette senden, DisplayClear, Cursor-Modus ändern 
usw...)

Jetzt mache ich die Busy-Abfrage und pulse 2mal das EN-Signal mit 
jeweils 5µs. Die ENABLE-Zeiten kann man sicher noch etwas verkürzen. Das 
werde ich noch testen.

Aber im großen Ganzen wird es sich wohl die Waage halten.

Für meine Zwecke sind diese Verzögerungen aber nicht wild.
Bin ja noch am Anfang und "spiele" :-)

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.