Forum: Mikrocontroller und Digitale Elektronik 16bit dividieren? Avr, C


von Strangelet (Gast)


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?

von Karl H. (kbuchegg)


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.

von Krapao (Gast)


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

von Ralph (Gast)


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.

von spess53 (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.