Hallo!
Ich versuche seit paar tagen auf mein 8051 ein lauflicht zu
programmieren, leider ohne erfolg.
Da ich mir die programmier sprache C selber beigebracht habe, fehlen mir
auch einige grundlagen. Ich hoffe Ihr könnt mir helfen.
#include <sfr51.h>
void warte(void);
main()
{
{
P0=0x01; // Anfangswert.
while(1)
{
warte (); // Aufruf der Funktion warte.
P0=P0<<1; // Bit um eins nach Links verschieben.
warte (); // Aufruf der Funktion warte.
}
if (P0 == 0x80) // Prüfe ob P0 = 0x08 ist, wenn ja, setze
Ausgang.
{
P0=0x01;// Wieder auf Anfangswert.
warte ();// Aufruf der Funktion warte.
}
}
}
void warte(void)
{
int i;
for(i=0; i=50; i++) // Timer 50 mal wiederholen, da einer
durchlauf 20ms hat.
//50 x 20ms = 1sek.
{
TMOD = 0x01;
TF0 = 0;
TR0 = 0;
TL0 = 0x7D;
TH0 = 0xCA;
TR0 = 1;
while (TF0 == 0);
}
}
for(i=0;i=50;i++)// Timer 50 mal wiederholen, da ein Durchlauf 20ms hat.
5
//50 x 20ms = 1sek.
6
{
7
TMOD=0x01;
8
TF0=0;
9
TR0=0;
10
TL0=0x7D;
11
TH0=0xCA;
12
TR0=1;
13
while(TF0==0);
14
}
15
}
Deine Warte-Funktion hat auch noch einen Fehler. Zu mindestens wenn sie
so funktionieren soll wie angegeben.
Da für die Bedingung für die Schleife bei dir "i=50" lautet, wird die
Schleife sofort abgebrochen. Wenn du 50 Durchläufe haben willst, muss
die Bedingung so lange wahr sein, bis der fünfzigste Durchlauf erreicht
ist. Also so lange i kleiner als 50 ist, soll die Bedingung wahr sein.
Danke für die Unterstützung. Ich habe d Code geändert, aber es
funktioniert noch nicht richtig. Ein LED leuchtet auf und ds wars dann
auch.
main()
{
P2 = 0x01; //Anfangswert
while(1) //Dauerschleife
{
warte(); //Aufruf Funktion "Warte"
P2 = P2 <<1; //Bit um ein Feld nach links schieben
warte(); //Aufruf Funktion "Warte"
if(P2 == 0x80) //Prüfe ob die "8hex" anliegt, wenn ja,
setzte Ausgang wieder zurück
{
P2 = 0x01; //Ausgang wieder zurück setzen
warte(); //Aufruf Funktion "Warte"
}
}
}
// Unterprogramm----------------------------------------
void warte (void)
{
int i;
for (i=0;i<=50;i++) //Timer 50 mal wiederholen lassen da ein
Durchlauf 20ms hat (eingestellt)
{
TMOD = 0x01; //Starten des Timers 0
TF0 = 0;
TR0 = 0; //Timer stop
TL0 = 0xE5;
TH0 = 0xBE;
TR0 = 1; //Timer start
while (TF0 == 0); //Wiederhole solange kein Überlauf
}
}
Deine Verwendung des Timers ist etwas gewöhnungsbedürftig.
Normalerweise schreibt man eine Interrupt Service Routine, die dann das
Shiften übernimmt.
Versuch doch zunächst einmal ohne den Timer das Lauflicht zu
programmieren, indem Du in der warte-Funktion zunächst enmnal eine
Variable (long int) hochzählt. Dann bist Du zumindest unabhängig von der
Timer-Programmierung.
Ich werde überigens im Juli meinen 8051-Kurs weitermachen.
Der Timer kommt ziemlich am Anfang.
Vielleicht hast Du ja Interesse.
http://et-tutorials.de/mikrocontroller/
ET-Tutorials schrieb:> Deine Verwendung des Timers ist etwas gewöhnungsbedürftig.> Normalerweise schreibt man eine Interrupt Service Routine, die dann das> Shiften übernimmt.
Nein.
Man kann auch auf jede Interruptquelle (z.B. Timerüberlauf) pollen und
dann das Flag händisch löschen.
Wenn man nur Däumchen drehen will, ist ein Interrupt nur unnötig
aufwendig.
Einen Interrupt braucht man nur, wenn man in der Zwischenzeit noch was
anderes machen will.
Peter
Hallo!
Hab gerade erst mit dem Programmieren in C für den Mikrokontroller
angefangen. Daher kann ich nicht ganz verstehen, warum meine
Timerfunktion ungewöhnlich ist.
Okay. Werden dann mal die Timerfunktion deaktivieren und Sie mit einem
long int hochzählen.
Würde gern trotzdem verstehen, warum es nicht funktioniert.
Bezüglich Deines Angebots für 8051 würd ich gern darauf zurück kommen.
ET-Tutorials schrieb:> Versuch doch zunächst einmal ohne den Timer das Lauflicht zu> programmieren, indem Du in der warte-Funktion zunächst enmnal eine> Variable (long int) hochzählt. Dann bist Du zumindest unabhängig von der> Timer-Programmierung.
Das ist die schlechteste Lösung, da Trial & Error.
Man hat keinerlei Kontrolle darüber, wie lang das Delay ist. Änderungen
von Compilerversion und Compileroptionen können das Ergebnis
beeinflussen.
Sowas sollte man daher nur im aller äußersten Notfall machen (z.B. alle
Timer belegt).
Mit dem Timer kann man die Zeit aber exakt ausrechnen, hinschreiben,
compilieren, flashen und es stimmt auf Anhieb.
Manche Compiler haben eine Delay-Lib, der man die Zeit (µs, ms, s)
übergeben kann. Dann stimmt das Delay auch, solange es nicht durch
andere Interrupts zu stark verzögert wird.
Ohne Delay-Lib ist aber immer der Timer die beste Wahl.
Peter
> Einen Interrupt braucht man nur, wenn man in der Zwischenzeit noch was
anderes machen will.
Hallo Peter,
Danke für dein Kommentar. Wie du schon gemerkt hast, bin ich ein
Grünschnabel in Sachen C Programmierung. Es wäre super wenn du mir sagen
könntest, was ich falsch gemacht habe.
Eine Interrupt Funktion wollte ich noch nicht einfügen, da mir hier noch
die nötige Einarbeitung fehlt.
Wenn Du die LEDs direkt an P2 gelegt hast, könnte es sein, daß der MC
immer 0x00 einliest und schiebt.
Leg Dir ne Hilfsvariable an und gib diese auf P2 aus.
Peter
Hallo Peter,
natürlich ist Zählen keine schöne Lösung, da gebe ich Dir recht.
Meine Erfahrung aus dem Unterricht ist aber, dass sich Schüler im ersten
Schritt mit dem Zählen einfacher tun.
Also erst die Baustelle Bitshiften und dann die Baustelle Timer.
Bei 2 Baustellen verlieren Einsteiger meiner Erfahrung nach schneller
die Übersicht.
Und natürlich kann man auch das Interrupt Pendig-Flag pollen.
Aber wie gesagt, mein (Lehrer-)Ansatz wäre da schrittweise ranzugehen.
Just my 2 Cents.
Mike S. schrieb:> Da für die Bedingung für die Schleife bei dir "i=50" lautet, wird die> Schleife sofort abgebrochen.
Falsch! Das ist eine Zuweisung, die als boolcher Ausdruck interpretiert
immer wahr ist. Das ist also eine Endlosschleife.