16bit dividieren? Avr, C

Gast #2642755
Hallo,

Für eine Drehzalmessung möchte ich mit einem AVR den 16bit Wert eines 
Timers dividieren. Wie mach ich das, ich vermute ich kann nicht einfach:
1
timer1var = TCNT1 / 256;
machen oder? Weil ich TCNT1H und TCNT1L hab. Ich hab momentan Leider 
kein LCD mit dem ich das Testen könnte.

Kann mir wer helfen?
Strangelet schrieb:
> Hallo,
>
> Für eine Drehzalmessung möchte ich mit einem AVR den 16bit Wert eines
> Timers dividieren. Wie mach ich das, ich vermute ich kann nicht einfach:
>
1
timer1var = TCNT1 / 256;

manchmal kann die Welt so einfach sein.
Doch. Du kannst

> machen oder? Weil ich TCNT1H und TCNT1L hab.

Das weiß aber auch dein gcc-Compiler und ersetzt einen Zugriff auf TCNT1 
durch 2 Zugriffe auf das High und Low Register. Für dich bedeutet das: 
Du hast ein 'Pseudo'-16-Bit-Register TCNT1. Wie sich das in TCNT1H und 
TCNT1L aufteilt braucht dich nicht zu interessieren.
Gast
/256 ist bei unsigned ein Shift um 8 Bits nach Rechts
Bitmanipulation

Du kannst auch das Lowbyte wegwerfen. Obacht lesen musst du es wegen der 
besonderen Pufferung von 16-Bit SFRs im AVR trotzdem [[AVR 
16-Bit-Register]].

Falls TCNT1L und TCNT1H bei deinem AVR nicht an aufeinander folgenden 
Speicherstellen stehen, so dass du TCNT1 nicht verwenden kannst:
1
TCNT1L;             // LOW-Byte lesen und verwerfen
2
timer1var = TCNT1H; // HIGH-Byte lesen und verwenden
Gast
also wenn du es ganz sicher ohne Risiko einer Zugriffsverletzung haben 
willst, dann so:

1. Anlegen einer Temporärer Variable der Größe unsigned 16 ( U16 Temp)
2. TimerStop ( ich weiß jetzt nicht wie das entsprechende Register beim 
AVR heißt)
3. Temp = TCNT1
4. TimerStart
5. x = Temp / 256

Nachteil:
Das ergibt einen beeinträchtigten Zählerwert.
Allerdings ist ja bekannt wie lange der Timer angehalten ist.
Also kann vor Timerstart ein entsprechend korrigierter Timerwert nach 
TCNT1 geladen werden.
Um die Schritte 2 - 4 lässt sich dann auch noch eine Interruptsperre 
legen, um diesen Zeitversatz reproduzierbar gleich zu halten.
Gast
Hi

>2. TimerStop ( ich weiß jetzt nicht wie das entsprechende Register beim

Unnötig. Beim Lesen von TCNT1L wird TCNT1H automatisch in einem 
temporären Register gepuffert. Beim Lesen von TCNT1H wird dieses 
Register gelesen. Damit entspricht TCNT1H dem Wert zum Zeitpunkt des 
Lesens von TCNT1L.

MfG Spess

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.