Forum: Mikrocontroller und Digitale Elektronik 32-bit counter mit ATMEGA88


von istschonputt (Gast)


Lesenswert?

Ich möchte einen Hardware 32-bit-Zähler mit dem Atmega88 aufbauen. 
Gezählt werden soll der Prozessorclock CLK=20 MHz. Der Zählerstand soll 
zu einem bestimmten Zeitpunkt durch die Software ausgelesen werden. 
Rücksetzen ist nicht nötig.

Das habe ich mir so vorgestellt:

- Timer/Counter 0 - 8 Bit - Quelle CLK - kein Prescaler
- Timer/Counter 1 - 16 Bit - Quelle CLK - Prescaler 1/256 - CTC-Mode - 
Ausgang OC1A
- Timer/Counter 2 - 8 Bit - Quelle: OC1A an TOSC1 - kein Prescaler

Das Datenblatt ist zum TC2 ein bisschen vage. Hat das jemand
schon einmal so versucht?

Mir ist bewusst, das beim Lesen der Zähler nacheinander der Zählerstand 
nicht konsistent ist, das würde ich aber durch die Software 
kompensieren.

Danke
A.

von Peter D. (peda)


Lesenswert?


von Flo (Gast)


Lesenswert?

nimm doch einen 16bit-timer, und zähl ne 16 bit variable (zb. time) im 
timer overflow interrupt hoch, beim auslesen musste mur
time als high 16 bit und tcnt als low 16bit auslesen.

von istschonputt (Gast)


Lesenswert?

Software geht leider nicht, da realtime Abläufe nicht unterbrechen 
werden können.

von Flo (Gast)


Lesenswert?

Gib mal nen groben Überblick von deinem Projekt, kann mir grad nicht 
vorstellen, dass du dein Hauptprogramm nicht ganz kurz unterbrechen 
kannst, wäre ja nur ~6 Takte alle 65536 Takte, also ~0,01%.

Ist die Vorgabe durch die Software bestimmt oder wegen besonders 
zeitkritischer Berechnungen?

von istschonputt (Gast)


Lesenswert?

Der grobe Überblick:

es wird ein externer Pin abgetastet, an dem ein Manchester-kodiertes 
Signal anliegt (1000 ns Bitlänge, d.h. Abtastung alle 500 ns = 10 
Taktzyklen). Die Abtastung muss genau 114 x 1000 ns ungestört ablaufen 
können. Am Ende wird dann der Zählerstand dazugespielt.

Nun alles klar? Ich hatte das bisher mit einem TTL-Grab extern 
dazugespielt, möchte das aber sparen.

von Michael B. (mb_)


Lesenswert?

istschonputt schrieb:
> Der grobe Überblick:
>
> es wird ein externer Pin abgetastet, an dem ein Manchester-kodiertes
> Signal anliegt (1000 ns Bitlänge, d.h. Abtastung alle 500 ns = 10
> Taktzyklen). Die Abtastung muss genau 114 x 1000 ns ungestört ablaufen
> können.

Dann schalte halt in diesen 114 microsekunden halt alle interrupts ab 
(cli).

von avr (Gast)


Lesenswert?

Wenn es so kritisch ist einfach einen kleinen Tiny als
Slave verwenden.
Der Mega88 hat einen CLKO-Pin den du zum Takten verwenden
kannst.
Damit kannst du dann einen 32-Bit-Zähler aufbauen
und seriell auslesen. Noch Triggereingang und fertig.

Kein TTL-Grab, kaum Platzbedarf.

avr

von Peter D. (peda)


Lesenswert?

istschonputt schrieb:
> Die Abtastung muss genau 114 x 1000 ns ungestört ablaufen
> können.

Kein Problem, dann wird eben der Interrupt für diese Zeit disabled.
Du mußt den Überlauf ja nicht sofort auswerten, es muß nur vor dem 
nächsten Überlauf erfolgen.
D.h. Du hast beim 16Bit Timer fast 65535 Zyklen Zeit für ne 
Interruptsperre.


Peter

von istschonputt (Gast)


Lesenswert?

Das Einlesen des Zählerwertes muss immer zum selben Zeitpunkt erfolgen, 
nämlich 8 µs nachdem eine Präambel erkannt worden ist und genau bevor 
die 114 µs starten. Wenn der Interrupt da gerade mal nicht durchkommen 
darf, ist der Zählerstand ja falsch.

von istschonputt (Gast)


Lesenswert?

avr schrieb:
> Wenn es so kritisch ist einfach einen kleinen Tiny als
> Slave verwenden.
> Der Mega88 hat einen CLKO-Pin den du zum Takten verwenden
> kannst.
> Damit kannst du dann einen 32-Bit-Zähler aufbauen
> und seriell auslesen. Noch Triggereingang und fertig.
>
> Kein TTL-Grab, kaum Platzbedarf.

Ebenfalls Problem mit der Synchronität beim Auslesen.

Aber ich wollte ja eigentlich wissen, ob ich mit dem Counter 2 das 
machen kann und mich nicht überzeugen lassen, das meine Anwendung nicht 
zeitkritisch ist. Sie ist es nämlich.

von Peter D. (peda)


Lesenswert?

istschonputt schrieb:
> Wenn der Interrupt da gerade mal nicht durchkommen
> darf, ist der Zählerstand ja falsch.

Nö.

Schau Dir mal mein Beispiel an, das Prinzip geht auch beim 16Bit Timer.
Die Ausleseroutine berücksichtigt das Überlaufbit. Sie muß nur innerhalb 
32767 Zyklen nach Überlauf aufgerufen werden.


Peter

von istschonputt (Gast)


Lesenswert?

Stimmt.

Bei 20 MHz findet der Überlauf für 24-bit alle 838 ms statt. Das sollte 
locker reichen.

Danke dafür.

Warum muss das Überlaufbit vor 32767 clocks ausgelesen werden, nur 
Interessehalber? Reichen nicht auch knapp 65536?

von spess53 (Gast)


Lesenswert?

Hi

>Warum muss das Überlaufbit vor 32767 clocks ausgelesen werden, nur
>Interessehalber? Reichen nicht auch knapp 65536?

Weil Bit15 als Überlaufbit fungiert.

MfG Spess

von istschonputt (Gast)


Lesenswert?

spess53 schrieb:
> Weil Bit15 als Überlaufbit fungiert.

Bit15?

Normal Mode
The simplest mode of operation is the Normal mode (WGM13:0 = 0). In this 
mode the counting direction is always up (incrementing), and no counter 
clear is performed. The counter simply overruns when it passes its 
maximum 16-bit value (MAX = 0xFFFF) and then restarts from the BOTTOM 
(0x0000). In normal operation the Timer/Counter Overflow Flag (TOV1) 
will be set in
the same timer clock cycle as the TCNT1 becomes zero. The TOV1 Flag in 
this case behaves like a 17th bit, except that it is only set, not 
cleared. However, combined with the timer overflow interrupt that 
automatically clears the TOV1 Flag, the timer resolution can be 
increased by software.
There are no special cases to consider in the Normal mode, a new counter 
value can be written anytime.

von Rolf Magnus (Gast)


Lesenswert?

> Gib mal nen groben Überblick von deinem Projekt, kann mir grad nicht
> vorstellen, dass du dein Hauptprogramm nicht ganz kurz unterbrechen
> kannst, wäre ja nur ~6 Takte alle 65536 Takte, also ~0,01%.

6 Takte vergehen bereits, bevor die ISR überhaupt anfängt.

von Peter D. (peda)


Lesenswert?

istschonputt schrieb:
> Warum muss das Überlaufbit vor 32767 clocks ausgelesen werden, nur
> Interessehalber? Reichen nicht auch knapp 65536?

Man kann das Überlaufbit und den Timer nicht gleichzeitig lesen und 
daher muß man beim Überlauf feststellen, ob der Timerwert vor oder nach 
dem Überlauf gelesen wurde.
Nach dem Überlauf ist das Bit15 = 0 bis zum Wert 32767.


Deine Idee mit T0 und dazu T1 mit Prescaler 256 klingt im ersten Moment 
nicht schlecht.
Aber sie ist es, da Du beide nicht gleichzeitig starten und lesen 
kannst.
D.h. da hast Du ähnliche Überlaufeffekte, aber mit dem großen 
Unterschied, daß Dir das T0-Überlaufbit nicht hilft, weil es immer 
gesetzt ist (Interruptsperre >256 Zyklen).
Du müßtest mehrmals lesen, d.h. hast unterschiedliche Auslesezeitpunkte 
und damit keine Genauigkeit auf einen Zyklus mehr.


Peter

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.