16bit dividieren? Avr, C

Gast #2642755
Lesenswert?

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?
#2642759
Lesenswert?

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 #2642767
Lesenswert?

/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 #2642863
Lesenswert?

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 #2642880
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren