Forum: Mikrocontroller und Digitale Elektronik Zeitmessung 80C517


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Marius M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Guten Tag zusammen,
ich beginne gerade mit Assembler programmierung an einem 80C517 mit 
12MHz und soll unter anderem eine kleine Zeitmessung programmieren.

Die Messung soll mit einem Port gestartet und gestoppt werden.
Und der Wert in ms über die serielle Schnitstelle ausgegeben werden.

Meine erste Idee war es natürlich das ganze mit einem Timer zu 
realisieren.
Ich hab mich erstmal für den timer1 entschieden, da ich durch das 16bit 
Register weniger Überläufe hab.

         mov TMOD, #00010001B
         clr tr0
         mov TH0, #0H
         mov TL0, #0H
         clr tf0

Ich warte nun auf das Setzten des Ports und starte dann den timer

         jb P4.1,$
         setb tr0
         call Timer1
         call Auswertung

Timer1:
         jnb tf0,$
         clr tf0
         inc 2DH  ;(Hier speicher ich die Timerüberläufe)
         jnb P4.1,Timer1
         clr tr0
         ret

Die Auswertung des Wert klappt, sprich die Umrechnung von 1,2 Registern 
in ms oder µs und bisschen Textausgabe über die Schnittstelle bekomme 
ich hin.

Mein größstes Problem ist gerade dass ich immer auf einen Timerüberlauf 
warte um diesen zu speichern und danach erst prüfe ob überhaupt noch 
gestoppt werden soll.
Sprich im ungünstigsten Fall ist mein Ergebnis um ~65,5 ms falsch.
Gibt es eine Möglichkeit den Timer direkt zu stoppen wenn mein Port 0 
ist und dennoch die Überläufe zu zählen, sodass ich später den aktuellen 
Timerstand auslesen kann?

Vielen Dank schonmal im Voraus

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Timer1:
         jnb tf0, _ti2
         clr tf0
         inc 2DH  ;(Hier speicher ich die Timerüberläufe)
_ti2:
         jnb P4.1, Timer1
         clr tr0
         ret

von HolgerT (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Beschäftige dich mit Interrupts.

Bei jedem Timerüberlauf lässt sich ein Interrupt generieren und du 
zählst in der Interruptserviceroutine dein Register (2Dh?) hoch.
Wenn Du über den Port das Stopp-Signal bekommst, wird nachgeschaut, wie 
viele Timerüberläufe in 2Dh stehen.

von Marius M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wow schon mal vielen Dank für die schnellen Antworten.

Die Idee von Peter ist ja wirklich simpel und funktioniert schon ganz 
gut -.-
Vermutlich könnte es sein, dass man einen Überlauf nicht mitbekommt wenn 
man dabei gerade den Port 4.1 prüft.
Die Wahrscheinlichkeit ist ziemlich klein aber vermutlich da.

Die Interupts hören sich interessant an, da werde ich mich mal etwas 
einlesen.

Nochmals vielen Dank!!

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Marius M. schrieb:
> Vermutlich könnte es sein, dass man einen Überlauf nicht mitbekommt

Daher erst T0 stoppen und danach Überlauf addieren:
Timer1:
         jnb P4.1, _ti2
         clr tr0
_ti2:
         jnb tf0, _ti3
         clr tf0
         inc 2DH  ;(Hier speicher ich die Timerüberläufe)
_ti3:
         jb tr0, Timer1
         ret

von Marius M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
villeicht versteh ich etwas falsch, aber ich glaube damit ist das 
Problem noch nicht ganz behoben.
Was ich meinte ist, dass der Prozessor durch das hin und her springen ~4 
Maschinenzyklen = 4µs beschäftigt ist und so lange den Timerüberlauf 
nicht prüft.
Sprich es besteht eine ~4:65536 Chance dass Überläufe nicht registriert 
werden.
Trotzdem schon eine schöne Lösung.

Aber ich denke ich versuche es mal mit den Interrupts.
Ich habe mich dazu jetz ein wenig eingelesen aber ich finde noch nichts 
genaues wie ich Start und Ende der Interupt-Service-Routine in meinem 
Code markiere.
Alles was ich finde sieht eher aus wie C:
void INTTIM0 (void) interrupt 1  
     {     
     }
Auf jeden Fall meckert mein Compiler über unbekannte Zeichen.
(Programmiere das ganze mit RIDE)
Kennt sich damit jemand aus, oder geht das mit Ride überhaupt?

Liebe Grüße
Marius

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Marius M. schrieb:
> Was ich meinte ist, dass der Prozessor durch das hin und her springen ~4
> Maschinenzyklen = 4µs beschäftigt ist und so lange den Timerüberlauf
> nicht prüft.

Wen störts, der nächste Überlauf kommt doch erst nach 65536µs, das 
sollte wohl reichen.

von Marius M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ach richtig da hatte ich doch nen Denkfehler, einfach zu warm heute...
Das Überlaufflag wird ja gar nicht automatisch gelöscht, das bleibt ja 
stehen. Ja dann passt das ja so.
Vielen Dank nochmals :D

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.