Differenz zwischen "übergelaufenen" Werten

Gast #3960368
Lesenswert?
• ▲
▼
Ich stehe im Moment mächtig auf dem Schlauch!
Ich möchte gern eine eigene Zeitmessung im Programm umsetzen. Alle Timer 
haben schon Ihre Aufgaben abbekommen (4 x PWM in Timer0 und Timer2, 
Timer1 Overflow Interrupt soll PWM-Values aktualisieren). Aus diesem 
Grund möchte ich TCNT1 benutzen um Zeitdifferenzen zu ermitteln. Da es 
zum Überlauf kommen kann, mache ich folgendes:
1
uint16_t My_Time_Dif(uint16_t cnt)  // Hier wird TCNT1 eingetragen
2
{
3
  static uint32_t lastTime;   // letzter Zeitstempel in meiner 
4
                                    // Zeitrechnung
5
  uint32_t now;
6
  uint32_t dif;
7
  
8
  now = cnt;
9
  
10
  if (now < lastTime)
11
  {
12
    now += 65536;
13
  }
14
  
15
  dif =  now - lastTime;
16
  
17
  lastTime = cnt;
18
  
19
  return (uint16_t) dif
20
}
und habe dabei ein komplett schlechtes Gewissen. Dieses rumhantieren mit 
16bit und 32bit Zahlen gefällt mir überhaupt nicht. Ich bin sicher das 
es viel einfacher geht.
Meine eigenen Berechnungen auf dem Zettel haben aber immer Mist ergeben, 
hat jemand eine Idee?
#3960387
Lesenswert?
• ▲
▼
ArduStemmi schrieb:
> (uint16_t) dif = (uint16_t) now - (uint16_t) lasttime;
Wenn du lastTime, now und dif als uint16_t deklarierst kannst du dir die 
ganzen Casts sparen.

> Ich hab' genau das mit der Hand gerechnet und komme eben nicht drauf!
> Warum ist das so?

Beispiel mit 3bit:

1)
Wert alt: 001 = 1d
Wert neu: 011 = 3d

-alt: 110 + 1 = 111 = -1d   // 2er-Komplement

neu + (-alt):
 011 +
 111
 ---
1010 = 2d   // Überlauf wird gelöscht, da nur 3bit Zahl


2)
Wert alt: 110 = 6d
Wert neu: 000 = 0d

-alt: 001 + 1 = 010 = -1d   // 2er-Komplement

neu + (-alt):
 000 +
 010
 ---
0010 = 2d

Der Timer hat bei beiden Beispielen um 2 weitergezahlt, das Ergebnis der 
Subtraktion bleibt das gleiche, da der Überlauf nicht berücksichtigt 
wird, da man konsequent nur mit 3bit Zahlen arbeitet.
Analog für 16bit, ich wollte mir aber etwas Schreibarbeit sparen.
Gast #3960451
Lesenswert?
• ▲
▼
ArduStemmi schrieb:
> Ich hab' genau das mit der Hand gerechnet und komme eben nicht drauf!

Dann hast du vermutlich die Rechenregeln für uint16 nicht vollständig 
berücksichtigt. Wenn du allerdings deinen Rechenweg auf ewig für dich 
behälst, wird dir auch keiner sagen können, was da schief gelaufen ist.
Gast #3960466
Lesenswert?
• ▲
▼
Herzlichen Dank! Dann habe ich mich auf meinem Zettel wohl verrechnet! 
Obwohl ich, wie Du, auch bloß mit 3bit gerechnet habe.

Ich glaube, man sollte nicht soviel arbeiten, zwischen den Wochenenden, 
das erschöpft und lenkt von den wichtigen Bits und Bytes ab!

Herzlichen Dank nochmal!

PS: Ich werde meinen Zettel nicht einscannen und hier posten, war ja eh 
falsch!

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.