Übung 8, 16-Bit-Timer/Counter

Wir wollen eine Zeitmessung zwischen 2 Ereignissen realisieren so wie sie z.B. bei Geschwindigkeitsmessungen verwendet wird.

Dazu schliessen wir am ICP ein Eingangssignal an. In der realen Welt könnte dies z.B. eine Lichtschranke sein. Wir nehmen hier der Einfachheit halber einen Taster.
Zusätzlich benötigen wir ein Triggersignal, welches die Zeitmessung startet. Auch hier könnte eine Lichtschranke verwendet werden. Wir schliessen hier aber einfach einen weiteren Taster an.

Wenn nun also das Triggersignal erkannt wird soll der Timer/Counter1 gestartet und auf 0 gesetzt werden. Wenn dann zu einem späteren Zeitpunkt die Flanke am ICP erkannt wird lesen wir den Wert des ICR1-Registers aus und berechnen anhand des Abstands der beiden virtuellen Lichtschranken die Geschwindigkeit. Das Resultat soll über den UART auf den PC übertragen und dort angezeigt werden (Terminal-Programm).

Tipps:

Für die Berechnung der Geschwindigkeit sollte keine Fliesskommaarithmetik verwendet werden da sonst der Speicher des 2313 im Null Komma Nichts voll ist wenn die entsprechende Bibliothek vom GCC dazu gelinkt wird.
Dies bedeutet, dass wir die einmal erworbenen Mathematik- und Algebrakenntnisse wieder hervorkramen müssen um die entsprechenden Formeln zu erhalten.

Verwendete Formelzeichen:

s Wegstrecke bzw. Abstand zwischen den beiden Signalgebern.
Ich habe mit einem Abstand von 20 cm gerechnet, was 1/5 m entspricht.
t Zeit, welche benötigt wird um die Strecke s zu durchfahren, in Sekunden. Bei einer CPU-Taktrate von 10 MHz und einem Vorteiler von 8 ergibt sich eine Taktzeit am Timerausgang von 0.0000008 bzw. 1/1250000 Sekunden.
v Geschwindigkeit in m/s.
Wenn wir diese noch mal 3600 und dann geteilt durch 1000 rechnen erhalten wir die Geschwindigkeit in km/h.
x Anzahl Zählimpulse während der Durchfahrt. Diese müssen dann mit t multipliziert werden.
Wenn wir auch langsamere Geschwindigkeiten erfassen wollen müssen wir den Überlauf des Timers ebenfalls auswerten und die Anzahl Durchläufe mit einberechnen.

 

Die Grundformel für die Geschwindigkeit lautet:   

v=s/t

Mit s=1/5 und t=x * 1/1250000: v=(1/5) / (x*1/1250000)
Wenn wir nun noch wissen, dass man Brüche dividiert, indem man mit dem Kehrwert des zweiten Bruchs multipliziert, dann wird daraus: v=(1/5) * (1250000/x)
Das ganze dann noch ein wenig gekürzt: v=250000/x
Und jetzt noch in km/h umrechnen: v=(250000*3600)/(x*1000)
Und nochmal kürzen: v=(250*3600)/x
ergibt schlussendlich: v=900000/x

Da wir hier mit grossen Zahlen rechnen müssen entsprechend long-Variablen verwendet werden. Desweiteren sollte immer zuerst multipliziert und erst dann dividiert werden, da sonst durch die Integerarithmetik zu viel weggeschnitten wird.
Nehmen wir dazu mal folgendes einfaches Beispiel:

x = 15 / 4 * 8

Wenn wir zuerst die Division durchführen erhalten wir 15 / 4 = 3.75. Dies wird aber auf 3 geschnitten. Diese 3 multipliziert mit 8 ergibt 3*8=24.

Führen wir aber zuerst die Multiplikation aus so ergibt sich 15 * 8 = 120 und diese 120 / 4 = 30.

Versuch doch einfach einmal, das Programm selbst zu entwickeln.
Wenn es überhaupt nicht gelingen sollte dann geht's hier zur Musterlösung mit zugehörigem Makefile.
Zur Ausgabe der Resultate kann die bereits früher verwendete Funktion UartPrintF verwendet werden. Hier ist die zugehörige Headerdatei.

Ich habe versuchsweise einmal anstelle der Taster 2 Reed-Kontakte angeschlossen und bin mit einem Dauermagneten darüber gefahren. Auf diese Art und Weise könnte beispielsweise eine Geschwindigkeitsmessung bei einer Modelleisenbahn realisiert werden. Die Reedkontakte werden einfach in die Schienen montiert und unter der Lok oder einem Wagen wird ein Magnet befestigt. Die Anzeige sollte dann allerdings nicht unbedingt in km/h erfolgen oder wenn, dann im entsprechenden Massstab reduziert.