Forum: Mikrocontroller und Digitale Elektronik mal wieder Busy-Flag


von Peter (Gast)


Lesenswert?

Hallo liebes Forum,

ich weiß es gibt hier einige Codebeispiel und ich habe sie schon alle 
durch, allerdings hat mich kein einziger Codeteil weitergebracht.
Ich bin echt am verzweifeln. Das müsste doch ganz einfach sein.
Ich lese das Busy-Flag von einem HD44780 im 4-Bit Mode.


void toggle_enable(void)
{
   LCD_PORT |= (1<<LCD_EN);    // EN- Pin auf 1 setzen
   delay(1);
   LCD_PORT &= ~(1<<LCD_EN);  // EN- Pin auf 0 setzen
}

void read_busy_flag(void)
{
  DDRA &= ~( (1 << DDA0) | ( 1<<DDA1) | ( 1<<DDA2) | ( 1<<DDA3) );  // 
Pin 0-3 als Eingang

  LCD_PORT &= ~(1<<LCD_RS);  // RS- Pin auf 0 setzen
  LCD_PORT |= (1<<LCD_RW);  // RW- Pin auf 1 setzen

    while(a != 0)
    {
      toggle_enable();
      a = (LCD_PIN & 0x01);  // obere Nibble einlesen  (DB4 - DB7)
      toggle_enable();
      b = LCD_PIN;      // untere Nibble einlesen (DB0 - DB3)
  }

    DDRA |= ( (1 << DDA0) | ( 1<<DDA1) | ( 1<<DDA2) | ( 1<<DDA3) );  // 
Pin 0-3 als Ausgang
    LCD_PORT &= ~(1<<LCD_RW);    // RW- Pin auf 0 setzen
}

Ich weiß echt nicht mehr weiter. Seht ihr vielleicht einen Fehler??

Viele Grüße und ein frohes Fest euch allen!!
Peter

von (prx) A. K. (prx)


Lesenswert?

Peter schrieb:

>       a = (LCD_PIN & 0x01);  // obere Nibble einlesen  (DB4 - DB7)

Bit 4???

von Hc Z. (mizch)


Lesenswert?

>     while(a != 0)

Die zurückgelesenen Daten enthalten nicht nur das Busy-Flag, sondern 
auch die Displayadresse.  Es ist also nicht gesagt, dass a = 0 ist, wenn 
Busy = 0 ist.  Du musst auf a & Bit3 testen.

von (prx) A. K. (prx)


Lesenswert?

Hc Zimmerer schrieb:

> Die zurückgelesenen Daten enthalten nicht nur das Busy-Flag, sondern
> auch die Displayadresse.

Er maskiert doch schon beim Lesen. Nur eben auf das falsche Bit.

von Hc Z. (mizch)


Lesenswert?

Ja, stimmt.  Habe ich übersehen.

von Peter (Gast)


Lesenswert?

Hallo zusammen,

Danke das ihr euch mein Problem angenommen habt aber auch das prüfen auf 
das 7., richtige Bit, hat keinen Erfolg gebracht!!!


void read_busy_flag(void)
{
  DDRA &= ~( (1 << DDA0) | ( 1<<DDA1) | ( 1<<DDA2) | ( 1<<DDA3) );  //
Pin 0-3 als Eingang

  LCD_PORT &= ~(1<<LCD_RS);  // RS- Pin auf 0 setzen
  LCD_PORT |= (1<<LCD_RW);  // RW- Pin auf 1 setzen

    while(a != 0)
    {
      toggle_enable();
      a = (LCD_PIN & 0x08);  // obere Nibble einlesen  (DB4 - DB7) und 
7. Bit prüfen
      toggle_enable();
      b = LCD_PIN;      // untere Nibble einlesen (DB0 - DB3)
  }

    DDRA |= ( (1 << DDA0) | ( 1<<DDA1) | ( 1<<DDA2) | ( 1<<DDA3) );  //
Pin 0-3 als Ausgang
    LCD_PORT &= ~(1<<LCD_RW);    // RW- Pin auf 0 setzen
}

Es ist so, dass ich den Quellcode für mein Display hier aus dem Tutorial 
verwende. Dort sind in einigen Funktionen, "Delayaufrufe" drin. Diese 
wollte ich durch das abfragen des busy-bit ersetzen. Das heißt wenn ich 
meine Quellcode mit den herkömmlichen delays laufen lasse, dann geht 
alles, ersetze ich aber die delays mit der Funktion "read_busy_flag" 
dann kommen nur seltsame Zeichen auf dem Display

von (prx) A. K. (prx)


Lesenswert?

Kann es sein, dass du alle Delays durch diese Abfrage ersetzt hast? 
Einige Delays in der Initialisierung müssen bleiben.

LCD-Code mit Busy-Abfrage findet man bei Peter Fleury,

von (prx) A. K. (prx)


Lesenswert?

Kleine Stilfrage, da a,b nirgends deklariert sind: Sind das globale 
Variablen? Arg unübliche Programmiertechnik.

von Peter (Gast)


Lesenswert?

Hallo zusammen.
@A.K.
Du hast recht aber ich war bis eben seit gestern total am verzweifeln. 
Ich arbeite mit WINAVR/Eclipse AVRStudio4.0 und den Dragon. Ich hatte 
das Problem dass ich die obige Funktion nicht richtig "debugen" konnte. 
Ich habe alles versucht aber die Variablen wurden einfach nicht 
berücksichtigt und geändert. Deshalb habe ich auch mal probier die 
Variable global zu machen. Auch das brachte überhaupt kein Erfolg. 
Selbst beim debuggen wurde der Befehl " a = (LCD_PIN & 0x08);" zwar 
abgearbeitet aber die Variable hatte sich nicht geändert.
Dann eben die rettende Lösung....

DAS SCHEIß "OPTIMIZATION LEVEL" STAND, WARUM AUCH IMMER, AUF [SIZE 
OPTIMIZATION]

Ich habe ja ein neues Projekt angelegt und nicht darauf geachtete. Habe 
das ganze auf [No Optimization] geändert und jetzt funktioniert auch die 
busy-flag abfrage!!!

Also dann wünsch ich dem Forum noch schöne Feiertage...

Grüße Peter

von Purzel H. (hacky)


Lesenswert?

Uebrigens. Man kann sich das Busyflag bei einem Display schenken wenn 
man mit delays arbeitet. Ich zB hab einen 10ms timer, der auch wieder 
mal ein Zeichen an den Dispay schickt.

von (prx) A. K. (prx)


Lesenswert?

Peter schrieb:

> DAS SCHEIß "OPTIMIZATION LEVEL" STAND, WARUM AUCH IMMER, AUF [SIZE
> OPTIMIZATION]

Das ist meistens die richtige Einstellung. Für Programmierfehler 
deinerseits kann das Studio nichts. Wenn ein Programm nur ohne 
Optimierung funktioniert, dann ist in 99,9% der Fälle der Programierer 
selbst dran schuld.

Beispielsweise weil einfache Delayloops wegoptimiert werden. Weshalb es 
in der Lib passende Funktionen gibt. Die übrigens nur mit Optimierung 
korrekt funktionieren.

von (prx) A. K. (prx)


Lesenswert?

Nebliger Pfad schrieb:

> Uebrigens. Man kann sich das Busyflag bei einem Display schenken wenn
> man mit delays arbeitet. Ich zB hab einen 10ms timer, der auch wieder
> mal ein Zeichen an den Dispay schickt.

Lies den Thread lieber mal von oben durch...

von Peter D. (peda)


Lesenswert?

Peter schrieb:
> DAS SCHEIß "OPTIMIZATION LEVEL" STAND, WARUM AUCH IMMER, AUF [SIZE
> OPTIMIZATION]

Das ist auch gut so, nur damit erreicht man optimalen Code.
Ich nehme nie was anderes.

> Ich habe ja ein neues Projekt angelegt und nicht darauf geachtete. Habe
> das ganze auf [No Optimization] geändert und jetzt funktioniert auch die
> busy-flag abfrage!!!

Das deutet dann zu 99,9% auf ein Timingproblem hin.

Wenn es Dich aber nicht stört, daß Code 1000% größer ist und 1000% 
länger braucht, dann schalte ruhig die Optimierung aus, statt einfach 
das Datenblatt zu lesen und das richtige Timing zu implementieren.


Der AVR-GCC macht es einem doch sehr leicht, korrekte Timings zu 
implementieren mit den Macros der Delay.h: _delay_us() und _delay_ms().

Und vor allem ist der Code dann mittels F_CPU and den CPU-Takt anpaßbar.


Peter

von Peter D. (peda)


Lesenswert?

Nebliger Pfad schrieb:
> Uebrigens. Man kann sich das Busyflag bei einem Display schenken wenn
> man mit delays arbeitet.

Deshalb machen das ja auch 99% der Programmierer so (spart einen IO-Pin 
ein ohne merkbaren Nachteil).


Es ist schon sehr lustig, daß er nun die Optimierung abschaltet.

Statt also einen klitzekleinen Geschwindigkeitszuwachs durch die 
Busy-Abfrage zu erzielen, macht er lieber den Code erheblich langsamer, 
als er mit festen Delays wäre.


Peter

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.