Forum: Compiler & IDEs 8051 Lauflicht mit C


von ** *. (newman8051)


Lesenswert?

Hallo!

Ich versuche gerade ein Lauflicht in C zu programmieren, allerdings ohne 
erfolg.
Ich glaube es liegt a Timer.
Kann mir jemand hier helfen?

#include <sfr51.h>
void delay (void);
void main()
{
    P0 = 0x01;
    delay();

           P0= P0 >> 1;
            delay();

      if(P0=0x80)
        {
            P0=0x01;
        }


}

void delay (void)
{
    TMOD &=0xF0;
    TMOD |=0x01;
    ET0 =0;
    TH0 =0xFD;
    TL0 =0xFE;
    TF0 =0;
    TR0 =1;
    while(TF0==0);
    TR0=0;

}

Vielen dank.

von Peter II (Gast)


Lesenswert?

** ** schrieb:
>  if(P0=0x80)

das ist eine zuweisung und kein Vergleich!

 if(P0==0x80)

von XXX (Gast)


Lesenswert?

Hallo

Und das ganze wird exakt einmal durchlaufen!

Gruß
Joachim

von ** *. (newman8051)


Lesenswert?

>das ist eine zuweisung und kein Vergleich!

>if(P0==0x80)


Ich habe es geändert, auch hier ist nichts passiert. Die erste LED 
leuchtet und dann läuft das Licht einfach nicht weiter.

ist der Time falsch???

von XXX (Gast)


Lesenswert?

Ich wiederhole mich ungern:

Hallo

Und das ganze wird exakt einmal durchlaufen!

Gruß
Joachim

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo,

In main brauchste eine Endlosschleife. Der Timer geht so nicht. Den 
musste am Anfang starten. Das Umschalten der LEDs musst Du dann in einer 
Interrupt Routine machen.

Gruß aus JAPAN

BerndB

von ** *. (newman8051)


Lesenswert?

Sry Joachim hab deine Antwort nicht gesehen.

Hier habe ich die while Schleife vergessen. Aber trotzdem funktioniet es 
nicht.

#include <sfr51.h>
void delay (void);
void main()
{
while(1)
 {
    P0 = 0x01;
    delay();

           P0= P0 >> 1;
            delay();

      if(P0==0x80)
        {
            P0 = 0x01;
        }

 }
}

void delay (void)
{
    TMOD &=0xF0;
    TMOD |=0x01;
    ET0 =0;
    TH0 =0xFD;  --> wenn ich hie die Werte änder sehe ich die LEDs sehr 
schwach blinken (3C)
    TL0 =0xFF; --> (B0)
    TF0 =0;
    TR0 =1;
    while(TF0==0);
    TR0=0;

}

von ** *. (newman8051)


Lesenswert?

Hallo BerndB

> In main brauchste eine Endlosschleife.
> Der Timer geht so nicht. Den
>musste am Anfang starten.

void main()
{
  while(1)
  {
    delay();
    P0 = 0x01;
    delay();

           P0= P0 >> 1;
            delay();

      if(P0==0x80)
        {
            P0 = 0x01;
        }
   }

}
Ich habe mein void main() überarbeitet, ist das richtig so???

Geht das auch ohne Interrupt? Ich bin eigentlich noch ganz am anfang und 
habe mir die Sprache C soweit wie es geht selber beigebracht.

vielen dank

von ziegenpeter (Gast)


Lesenswert?

Versuchs mal mit

P0= P0 << 1;

von martin (Gast)


Lesenswert?

Ich wuerde mal sagen  die shift-Richtung ist falsch.

von ziegenpeter (Gast)


Lesenswert?

und die while schleife hinter dem
 P0 = 0x01;

von ** *. (newman8051)


Lesenswert?

>Versuchs mal mit

>P0= P0 << 1;

Ne auch nicht. Kann ich es auch ohne Timer machen?

einfach: i=0x00;
         i++;

        if(i!=0xFF)
         {
           goto einfach;
         }
danke

von Peter D. (peda)


Lesenswert?

P0 ist open-drain, da ergibt Rücklesen nur Bockmist. Nimm ne Variable.


Peter

von ** *. (newman8051)


Lesenswert?

>P0 ist open-drain, da ergibt Rücklesen nur Bockmist. Nimm ne Variable.

void main()
{
    int i=0x01;
    P0 = i;
    while(1)
  {
    delay();

           P0= i << 1;
            delay();

      if(i==0x80)
        {
            P0 = 0x01;
        }
   }

}

wäre ds so richtig?
danke

von Peter II (Gast)


Lesenswert?

** ** schrieb:
> wäre ds so richtig?

nein, wie soll denn i seinen wert ändern?

von ** *. (newman8051)


Lesenswert?

>wie soll denn i seinen wert ändern?

void main()
{
    int i=0x01;
    i++;
    P0 = i;
    while(1)
  {
    delay();

           P0= i << 1;
            delay();

      if(i==0x80)
        {
            P0 = 0x01;
        }
     else
        {
          P0 = P0<<1;
        }

   }
}
Ich glaube,dass ich jetzt noch mehr mist gemacht habe wie vorhin^^.

von martin (Gast)


Lesenswert?

if(i==0x80)
        {
            i = 0x01;
        }

Konzentration, Mann!

von Peter II (Gast)


Lesenswert?

** ** schrieb:
> Ich glaube,dass ich jetzt noch mehr mist gemacht habe wie vorhin^^.

so ist es.

Denke noch mal ganz in ruhe drüber nach, wie das Programm durchlaufen 
wird und was wann passiert.

von ** *. (newman8051)


Lesenswert?

void main()
{
    int i=0x01;
    i++;

while(1)
  {
           delay();
           P0= i;
           delay();

      if(i==0x80)
        {
            P0 = 0x01;
        }
     else
        {
          P0 = P0<<1;
        }

   }
}

von martin (Gast)


Lesenswert?

ey!


wenn i 0x80  ereicht  musst Du  i auf  0x01  zuruecksetzen
und dann  i  an  P0  zuweisen

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo,

das mit dem delay(), geht so nicht. Vor der While Schleife musst Du den 
Timer Initialiesieren. In de While Schleife auf das TF0 warten. den 
Timer stoppen. TF0 zurücksetzen. Neuen Timer Startwert setzen. Timer 
starten. LED setzen.

Der Timer Startwert von 0xFDFF ist vermutlich zu hoch. Das hängt 
natürlich vom Takt ab.

Gruß aus JAPAN,

BerndB

von Gunther (Gast)


Lesenswert?

i++...

Hmmmm....

von Stefan E. (sternst)


Lesenswert?

Ich liebe Programmieren per Raten. Es gibt noch ein paar Permutationen 
von i/P0/Schieben/Zuweisen, die du noch nicht probiert hast.

Wie wäre es, wenn du erst mal überlegst, was was ist, und was damit bei 
jedem einzelnen Schritt deines Programms passiert (notfalls mit Papier 
und Bleistift), bzw. welche Schritte eigentlich passieren müssen, damit 
das Gewünschte dabei raus kommt. Mach erstmal ein Ablaufdiagramm.

von ** *. (newman8051)


Lesenswert?

void main()
{
    int i=0x01;
    i++;

while(1)
  {
           delay();
           P0= i;
           delay();

      if(i==0x80)
        {
            i = 0x01;
            P0 = i;
        }
  }
}

von Peter II (Gast)


Lesenswert?

schon nah dran - eine zeile muss noch verschoben werden.

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo,

für einen ersten Test kannste auch einfach P0++; machen.

Gruß aus Japan,

BerndB

von ** *. (newman8051)


Lesenswert?

> Mach erstmal ein Ablaufdiagramm.

Super idee, werde mir ds nochmal anschauen. Ich bin jetzt total 
verwirrt.

Danke für die Tipps.

von ** *. (newman8051)


Lesenswert?

>schon nah dran - eine zeile muss noch verschoben werden.

void main()
{
    int i=0x01;
    i++;

while(1)
  {
           delay();
           P0= i;
           delay();

      if(i==0x80)
        {
            i = 0x01;
        }
           P0 = i;

  }
}

von martin (Gast)


Lesenswert?

jetzt  hast Du das shiften  vergessen.

Aufmerksamkeitsspanne == 3 Zeilen

von ** *. (newman8051)


Lesenswert?

>jetzt  hast Du das shiften  vergessen.



void main()
{
    int i=0x01;
    i++;

while(1)
  {
           delay();
           P0= i;
           delay();
           P0 = P0 << 1;

      if(i==0x80)
        {
            i = 0x01;
        }
           P0 = i;

  }
}

von J.-u. G. (juwe)


Lesenswert?

** ** schrieb:
> if(i==0x80)

Wie soll i jemals diesen Wert erreichen?

von ** *. (newman8051)


Lesenswert?

>Wie soll i jemals diesen Wert erreichen?

void main()
{
    int i=0x01;
    i++;

von martin (Gast)


Lesenswert?

jetzt sind wir wieder da  wo wir  ganz  oben
schonmal waren, Meister.

Hies  es nicht Du  sollst  P0 nicht  zuruecklesen?
Was naemlich passiert wenn Du  P0  shiftest?

Du sollst  i shiften  und dann  auf  P0  zuweisen.
Und nix anderes

von Peter II (Gast)


Lesenswert?

** ** schrieb:
>>Wie soll i jemals diesen Wert erreichen?
>
> void main()
> {
>     int i=0x01;
>     i++;

und wie oft wird dieser code ausgeführt?

von martin (Gast)


Lesenswert?

void main()
{
    int i=0x01;
    // i++;         increment nur in der while schleife


while(1)
  {
           P0= i;
           delay();
           i = i << 1;

      if(i==0x80)
        {
            i = 0x01;
        }
          //  P0 = i;   einmal  zuweisung  in der while schleife reicht

  }
}

von ** *. (newman8051)


Lesenswert?

void main()
{
    int i=0x01;                    // i Anfangswert

while(1)                           //Schleife
  {
           i++;                    // i hochzählen
           delay();                // Unterprogramm delay aufrufen
           P0= i;                  // i in P0 laden
           delay();                // Unterprogramm delay aufrufen
           i << 1;                 // i shiften
           P0 = i;                 // i in P0 laden

      if(i==0x80)                  // wenn i 0x80 erreicht hat
        {
            i = 0x01;              // i auf Anfangswert setzen
        }
           P0 = i;                 // i in P0 laden

  }
}

von Peter II (Gast)


Lesenswert?

** ** schrieb:
> i << 1;                 // i shiften

diese zeile macht nichts.

von martin (Gast)


Lesenswert?

und jetzt noch  i++ loeschen , das braucht keiner,
du shiftest ja schon

von martin (Gast)


Lesenswert?

> i << 1;                 // i shiften

>>diese zeile macht nichts.

echt ?  scheiss- Prozessor.

Dann eben  i=i*2 ;

von Peter D. (peda)


Lesenswert?

martin schrieb:
>> i << 1;                 // i shiften
>
>>>diese zeile macht nichts.
>
> echt ?  scheiss- Prozessor.

Nö, das ist korrektes C.
Man darf das Ergebnis einer Operation verwerfen.


> Dann eben  i=i*2 ;

Das ist aber was völlig anderes.
Du weist das Ergebnis ja wieder zu.


Peter

von ** *. (newman8051)


Lesenswert?

Hallo Martin,

Ich habe es jetzt nach deine Anweisung ausprobiert, aber es funktioniert 
immer noch nicht.

Ist der Timer richtig(void delay (void)???


#include <sfr51.h>

void delay (void);

void main()
{
    int i=0x01;



while(1)
  {

           P0= i;
           delay();
           i = i << 1;

      if(i==0x80)
        {
            i = 0x01;
        }


  }
}
void delay (void)
{
    TMOD &=0xF0;
    TMOD |=0x01;
    ET0 =0;
    TH0 =0x3C;
    TL0 =0xB0;
    TF0 =0;
    TR0 =1;
    while(TF0==0);
    TR0=0;

}

von Peter D. (peda)


Lesenswert?

** ** schrieb:
> Ich habe es jetzt nach deine Anweisung ausprobiert, aber es funktioniert
> immer noch nicht.

Du weißt, was open-drain Ausgang bedeutet?

Zeig mal den Schaltplan.
Schalte mal die LED + Widerstand vom Pin nach VCC.


Peter

von ** *. (newman8051)


Lesenswert?

Hallo Peter,

Ich weis was Open- Drain heißt. ich habe ja schon ein Lauflicht in 
Assembler programmiert und es hat ja auch funktioniert. So bald ich hier 
die Warteschleife aufrufe bleibt das Programm stehen.

von martin (Gast)


Lesenswert?

Dann schmeiss mal das delay   raus  und bau ne
for  loop   als  ersatz ein.


Die Zuweisung  von eier 16(?)  bit Variablen auf einen
8(?) bit port  ist auch so ne Sache.

von Peter D. (peda)


Lesenswert?

Also bei mir funktioniert es.
Ein kleiner Fehler ist im Code, 0x80 wird nicht angezeigt.


Peter

von martin (Gast)


Lesenswert?

au mann wir  sind der lösung so nah ....

von martin (Gast)


Lesenswert?

Ich frag  mich bloss wie debuggt  man eigentlich den Code

von z.B.  einer  10 MIO teuren Tunnelbohrmaschine?

Auf  die Art und Weise hätte sich das Teil schon  10x  selbst zerlegt.

von ** *. (newman8051)


Lesenswert?

Hallo Leute,

Danke für die Infos. Hab jetzt doch noch einmal meine LED+Widerstand 
überprüft`und soweit ist alles in Ordnung.

Bitte schaut noch einmal über das programm drüber, da es nicht läuft.
Liegt es vielleicht an der include Datei?

Bei Peter funktioniert das kleine Programm. Versteh aber nicht warum!

// ------------- READS51 generated header --------------
// module  : C:\Programme\Rigel\Reads51\Work\test3\Lauflicht_2.c
// created : 15:06:34, Thursday, June 30, 2011
// -----------------------------------------------------

#include <sfr51.h>

// Deklarierung Unterprogramm---------------------------

void warte (void);

// Hauptprogramm----------------------------------------

main()
{
    int i = 0x01;              //Anfangswert
    while(1)                //Dauerschleife
    {
        warte();            //Aufruf Funktion "Warte"
        i = i<<1;           //Bit um ein Feld nach links schieben
        P0 = i;             //Ausgabe I an Port 0
        warte();            //Aufruf Funktion "Warte"

        if(i == 0x80)       //Prüfe ob die "8hex" anliegt, wenn ja, 
setzte Ausgang wieder zurück
        {
            i = 0x01;       //Ausgang wieder zurück setzen
            warte();        //Aufruf Funktion "Warte"
        }
    }
}

// Unterprogramm----------------------------------------

void warte (void)
{
    int k;
    for (k=0;k<=50;k++)     //Timer 50 mal wiederholen lassen da ein 
Durchlauf hat (eingestellt)
    {
        TMOD = 0x01;        //Starten des Timers 0 als Timer
        TF0 = 0;            //Timer flag auf 0 setzen
        TR0 = 0;            //Timer stop
        TL0 = 0x3C;         //Wert für Timer Flag Überlauf
        TH0 = 0xB0;
        TR0 = 1;            //Timer start
        while (TF0 == 0);   //Wiederhole solange kein Überlauf
    }
}

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.