Forum: Mikrocontroller und Digitale Elektronik Zeitfunktion generieren


von Sascha K. (quad2000)


Lesenswert?

Hallo an alle,

ich will in meinem µC Programm eine Zeitfunktion Einbauen und über ein 
Display ausgeben.
So soll es mal aussehen: xx Stunden  xx Minuten xx Sekunden.

Ich verwende ein AT89C51CC03
Datehblatt: 
http://www.atmel.com/dyn/resources/prod_documents/doc4182.pdf

Compiler: Keil µVision 3

Das habe ich mir überlegt:

//Initialisierung der Variablen usw. ist Vorausgesetzt
//zeits=Sekunden, zeitm=Minuten, zeith=Stunden


  if (TF0==1)    // Wenn TF0 Flag = 1 dann
  {
  TL0=0x00;      //Timer LowByte mit Wert laden
  TH0=0x3C;      //Timer LowByte mit Wert laden
  TF0=0BD;       //Flag des Timers rücksetzen
  zeit++;        //Variable "zeit" um 1 erhöhen

  if (zeit==20)
  {
    zeit1=0;
    zeits++;
  }
  if (zeits==60)
  {
    zeits=0;
    zeitm++;
  }
  if (zeitm==60)
  {
    zeitm=0;
    zeith++;
  }

Die Werte für TH0 und THL habe ich so gewählt, das der Timer 0 nach 50ms 
überläuft. Durch die if Schleife zeit==20 habe ich dann Sekunden usw.

Das diese Zeitfunktion nicht sehr genau ist weiss ich. Das ist aber auch 
nicht all zu wichtig.
Die Ausgabe über das Display funktioniert.

Nun meine Frage:
Kann ich das so verwirklichen oder gibt es besseere Möglichkeiten?
(ich denke mir, das ich das nicht gut gelöst habe)

Ich bin auch auf der Suche nach eine Lösung, die so wenig Zyklen wie 
möglich benötigt da parallel zu dieser Funktion ein Hauptprogramm 
abläuft, das eine höhe Priorität als die Zeitfunktion hat. Dabei handelt 
es sich um AD-Wandler. Die Wandlung wird in einer Endlosschleife 
durchgeführt. Es sollen so viele Wandlungen wie möglich durchgeführt 
werden.

Der obige Code soll in einer Fuktion stehen. Diese Funktion wollte ich 
über den internen Interrupt ansprechen.

Hat jemand eine Idee, wie ich das besser bewerkstelligen könnte?

Danke und ein schönes Wochenden Sascha

von Sascha K. (quad2000)


Lesenswert?

Hier ist mir ein Fehler unterlaufen:

  TL0=0x00;      //Timer LowByte mit Wert laden
  TH0=0x3C;      //Timer LowByte mit Wert laden
  TF0=0BD;       //Flag des Timers rücksetzen
  zeit++;        //Variable "zeit" um 1 erhöhen


So ist es richtig:

  TL0=0xBD;      //Timer LowByte mit Wert laden
  TH0=0x3C;      //Timer HighByte mit Wert laden
  TF0=0;         //Flag des Timers rücksetzen
  zeit++;        //Variable "zeit" um 1 erhöhen

von Sascha K. (quad2000)


Lesenswert?

Hat niemand eine Idee?
Oder ist meine Beschreibung nicht ausreichend?

von Matthias L. (Gast)


Lesenswert?

>if (zeit==20)
>  {
>    zeit1=0;

Das sollte wohl in beiden Fällen die selbe Variable sein..


>die so wenig Zyklen wie möglich benötigt
Dann mache den Interrupt möglichst so, dass er nur alle eine Sekunde 
auftritt.

von Matthias (Gast)


Lesenswert?

Dein Ansatz ist erstmal richtig.

> if (TF0==1)    // Wenn TF0 Flag = 1 dann

wenn die Routine im Interrupt läuft, kannst Du auf diese Abfrage von TF0 
verzichten. TH0, TL0 nachladen genügt. TF0 rücksetzen ist auch nicht 
nötig.

Ideal wäre ein Interrupt im 1s Raster. Diese große Zeit wirst Du mit 
einen 16Bit-Timer der 8051er normalerweise nicht erreichen können. (Es 
sei denn, Du arbeitest mit einen Quarz so um die 500kHz!) Deshalb sind 
die 50ms Zeitraster schon ok.

von Sascha K. (quad2000)


Lesenswert?

Danke für die Antworten,

hat mir sehr geholfen.

Nun Funktionierts.

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.