Forum: Mikrocontroller und Digitale Elektronik Problem 16Bit Timer auslesen und zurücksetzen für Frequenzzähler ATmega1284p Assembler


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Geschätztes Forum,

der Timer1 (16Bit) wird durch ein externes Signal angesteuert, in diesem 
Fall mit 12MHz bei 24Mhz µC Takt. Der ATmega misst seine eigene 
Taktfrequenz (Flipp-Flopp dazwischen).

Nach 2s wird der Timerwert ausgelesen und anschließend sofort wieder auf 
Null gesetzt:
1
  LDS FREQENZ_L,TCNT1L ; auslesen LOW    
2
  LDS FREQENZ_H,TCNT1H ; auslesen HIGH    
3
  STS TCNT1H,NULL      ; Null HIGH
4
  STS TCNT1L,NULL      ; Null LOW

Problem: In der Zeit zwischen dem auslesen und rücksetzen des 
Timers1, das brauch auch einige Takte, zählt der Timer1 knadenlos 
weiter, so soll es auch sein.

Nur diese gezählten Impulse werden dann mit "STS TCNT1L,NULL" genullt.

Und es fehlen dadurch ca. 4 Impulse. Bei 24MHz, das sind unzumutbare 4Hz 
Ungenauigkeit.

Mir kam folgende Idee:

Nach einer kurzen Pause wird der Timer nochmals auselesen und zur 
ursprünglich gemessenen Frequenz dazuaddiert:
1
  LDS FREQENZ_L,TCNT1L ; auslesen LOW    
2
  LDS FREQENZ_H,TCNT1H ; auslesen HIGH    
3
  STS TCNT1H,NULL      ; Null HIGH
4
  STS TCNT1L,NULL      ; Null LOW
5
6
        nop            ; Pause
7
        nop
8
        nop
9
        nop  
10
11
  LDS R0,TCNT1L      ; auslesen LOW    
12
  LDS R1,TCNT1H      ; auslesen HIGH      
13
  add FREQENZ_L,R0   ; addieren
14
  adc FREQENZ_H,R1

Das funktioniert schon ganz gut.

Frage: Was haltet Ihr von dieser Variante, gibt es bessere Lösungen?


Bernhard

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Bernhard S. schrieb:
> Problem: In der Zeit zwischen dem auslesen und rücksetzen des
> Timers1, das brauch auch einige Takte, zählt der Timer1 knadenlos
> weiter, so soll es auch sein.

Der Profi setzt Zähler deshalb niemals zurück, sondern bildet einfach 
die Differenz zur letzte Auslesung.

Beitrag "AVR Timer mit 32 Bit"

von Stefan F. (Gast)


Lesenswert?

Ich würde ihn gar nicht zurück setzen sondern überlaufen lassen und mit 
einer Variable vergleichen.

vorher=TCNT1
...
zählen lassen
...
jetzt=TCNT1
diff=jetzt-vorher
...
weiter zählen lassen
...

Mit unsigned Integer Variablen klappt das prima. Es stört nicht, wenn 
der Timer zwischendurch überläuft.

Unsicher bin ich allerdings, was passiert, wenn der Timer hoch zählt 
während du den LOW und HIGH Anteil ausliest. Da musst du mal ins 
Datenblatt schauen. Ich meine mich daran zu erinnern, dass AVR den 
Konflikt automatisch (in Hardware) verhindern und man diese beiden 
Anteile deswegen in einer ganz bestimmten Reihenfolge auslesen muss.

Dass würde im Umkehrschluss bedeuten, dass dein Lösungsansatz nicht in 
Ordnung ist, weil einer der beiden Zugriffe nicht die vorgeschriebene 
Reihenfolge einhält.

Um welchen Mikrocontroller geht es konkret?

von Stefan F. (Gast)


Lesenswert?

Für den ATmega328 gilt:

"The Timer/Counter (TCNT1), output compare registers (OCR1A/B), and 
input capture register (ICR1) are all 16-bit registers. Special 
procedures must be followed when accessing the 16-bit registers."

Und die ist:

"Accessing the low byte triggers the 16-bit read or write operation. 
When the low byte of a 16-bit register is read by the CPU, the high byte 
of the 16-bit register is copied into the temporary register in the same 
clock cycle as the low byte is read.For a 16-bit read, the low byte must 
be read before the high byte."

von Bernhard S. (bernhard)


Lesenswert?

1000 Dank für die sehr wertvollen Tipps :-)

Stefan ⛄ F. schrieb:
> Um welchen Mikrocontroller geht es konkret?


ATmega1284p

von Stefan F. (Gast)


Lesenswert?

Bernhard S. schrieb:
> ATmega1284p

Dann schau mal in dessen Datenblatt. Vermutlich stehen dort die gleichen 
Sätze drin.

von Thomas K. (joshua314)


Lesenswert?

Morgen zusammen

Stefanus hat recht mit der reihenfolge der register. bin darauf auch 
schon reingefallen.

Zum Zähler bauen....
Erster Timer der zählt.
Zweiter Timer als Torzeit nehmen...
Ich hab es nicht mehr genau auf dem Schirm, aber da gibt es eine 
Verriegelung, dass der eine Timer nur zählt wenn der andere es zulässt.
Damit fallen die paar Zyklen weg, welche du für die Verarbeitung 
brauchst.
Damit brauchst du auch kein Assembler mehr, sondern könntest das sogar 
in einem langsamen Basic machen.

Gruß Thomas

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

ATMega1284P mit 24Mhz? Dann habe ich entweder ein altes Datenblatt oder 
das ist schon wieder typischer Heimschrauber-Murks mit 20% 
Übertaktung... und sich dann am Ende noch aufregen wieso der Scheiß-µC 
instabil läuft.

von Bernhard S. (bernhard)


Lesenswert?

Ben B. schrieb:
> Übertaktung... und sich dann am Ende noch aufregen wieso der Scheiß-µC
> instabil läuft.

Ich denke, Deine Wortwahl ist etwas verbesserungswürdig^^

Wo steht geschrieben, dass der µC instabil läuft?

Er läuft absolut stabil!

Die Erscheinung, dass er Eingangsimpulse verschluckt, tritt auch
bei 10MHz µC Takt und 4MHz Eingangsfrequenz auf.

Liegt an der momentanen Programmierung, sehr interessante 
Lösungsvarianten wurden schon angeboten. Einfach mal lesen ;-)

Nimm lieber eine "Praline" und geh in Dein Zimmer.

: Bearbeitet durch User
von mittelostniederfranke (Gast)


Lesenswert?

Bernhard S. schrieb:
> Ich denke, Deine Wortwahl ist etwas verbesserungswürdig^^

So lieben wir die Leute hier die Hilfe brauchen und wollen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> Wo steht geschrieben, dass der µC instabil läuft?
> Er läuft absolut stabil!
Abwarten, vielleicht kommt das noch. Ist halt immer etwas riskant wenn 
man Teile so weit außerhalb ihrer Spezifikationen betreibt.

von HildeK (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich meine mich daran zu erinnern, dass AVR den
> Konflikt automatisch (in Hardware) verhindern und man diese beiden
> Anteile deswegen in einer ganz bestimmten Reihenfolge auslesen muss.

Tut er, wie du schon gefunden hast.
Man kann aber auch einfach TCNT1 als 16-Bit-Wert lesen; in iom1284p.h, 
includiert über io.h, steht drin:
1
#define TCNT1 _SFR_MEM16(0x84)
Da erledigt das korrekte Lesen der Compiler ...
Wird in anderen 16-Bit-Registern oft auch so gemacht, z.B. ADC bzw. ADCW 
enthält bereits den 16-Bit-Wert aus ADCH und ADCL.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Die Methode Differenzmessung funktioniert schon ganz gut,

aber die letzte Ziffer wackelte doch hin und wieder.

Und genau dieses Thema wollte ich noch mit Euch besprechen.

Ursache: Ein Interrupt wird nicht taktgenau ausgeführt, ist z.B. der µC 
bei bei der Abarbeitung eines "ret" Befehls (4Takte), kann erst dann der 
Interrupt ausgeführt werden, wenn ret abgearbeitet ist.

Folgende Lösungsidee:

Ein Zusatztimer (1:1) läuft parallel mit und immer wenn der 
Tor-Interrupt abgearbeitet wird, wird auch der Zusatztimer ausgelesen 
und eine Wartezeit berechnet, so dass immer zum exakt gleichen Moment 
der Frequenzcounter ausgelesen wird.

Ergebnis: kein zappeln mehr, siehe Video

Vielleicht gibt es bessere Lösungen?
1
; TAKTKORREKTUR beim INTERRUPTAUFRUF                      
2
  LDS temp,TCNT2    ; Kontrolltimer auslesen  
3
  andi temp,0b00011111; 0...15          
4
  ldi ZL, LOW(TIM0_SPRUNGMARKE)
5
  ldi ZH,HIGH(TIM0_SPRUNGMARKE)
6
  add ZL,temp
7
  adc ZH,NULL
8
  IJMP        ; SPRUNG (Zeiger nach Z)
9
;-------------------------------------------------------------------------------
10
TIM0_SPRUNGMARKE:
11
  nop  ; 0
12
  nop  ; 1
13
  nop  ; 2
14
  nop  ; 3
15
  nop  ; 4
16
  nop  ; 5
17
  nop  ; 6
18
  nop  ; 7
19
  nop  ; 8
20
  nop  ; 9
21
  nop  ;10
22
  nop  ;11
23
  nop  ;12
24
  nop  ;13
25
  nop  ;14
26
  nop  ;15
27
  nop  ; 0
28
  nop  ; 1
29
  nop  ; 2
30
  nop  ; 3
31
  nop  ; 4
32
  nop  ; 5
33
  nop  ; 6
34
  nop  ; 7
35
  nop  ; 8
36
  nop  ; 9
37
  nop  ;10
38
  nop  ;11
39
  nop  ;12
40
  nop  ;13
41
  nop  ;14
42
  nop  ;15

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Falls PD6 und Timer2 frei sind: wie wäre es mit Input-Capture?

von S. Landolt (Gast)


Lesenswert?

PS:
Der Controller hätte während der Messung fast nichts zu tun - und könnte 
derweil gegen sich selbst Schach spielen, zum Beispiel.

von c-hater (Gast)


Lesenswert?

Bernhard S. schrieb:

> Ursache: Ein Interrupt wird nicht taktgenau ausgeführt, ist z.B. der µC
> bei bei der Abarbeitung eines "ret" Befehls (4Takte), kann erst dann der
> Interrupt ausgeführt werden, wenn ret abgearbeitet ist.
>
> Folgende Lösungsidee:
[...]

Also vorab schonmal: Wie schon von S. Landolt geschrieben, ist die beste 
(sogar die einzige wirkliche) Lösung die Nutzung der 
InputCapture-Funktionalität des Timers. Damit löst sich das Problem ohne 
jegliche Klimmzüge, was kein Zufall ist, weil diese Funktionalität halt 
genau für diesen Zweck existiert.

Zu deiner Idee: Das Prinzip deines Ansatzes funktioniert für einige 
Sachen, für Capture aber nun gerade nicht. Da verringerst du damit im 
Prinzip bloß die messbare Auflösung.

Das allerdings könnte man auch viel einfacher haben, indem du nämlich 
einfach bei deinem Messwert die letzten x Bits wegmaskierst. Beim 1284P 
würde man x mit 2 ansetzen, jedenfalls so lange im Programm keine 
Interruptsperren über mehr als vier Takte vorkommen und es keine 
konkurrierenden Interrupts gibt. Sprich: Messwert and ~3 und gut isses.

Ein funktionsgleiches Äquivalent zu dem von dir gezeigten Programm wäre 
übrigens mit x = 4, also Messwert and ~$f. Also eine Instruktion statt 
23...

von Knut (Gast)


Lesenswert?

Nur die Hardware-Routine Input-Capture vermeidet Fehler durch
Interrupt-Reaktionszeiten bei der Timer-/Counter-Erfassung.
Und selbst die hat schon den "Digitfehler" +/-1, von dem man
mittlerweile schon in der Grundschule gehört haben sollte.

Alles Andere KANN nicht genauer, als +/- 1 Takt sein, aber gern
viel ungenauer.

Selbst wenn das Hauptprogramm nur aus einer Schleife mit 1-Takt-
Befehlen besteht, kann der Interrupt beim Rücksprungbefehl
auftreten - und der dauert 2 Takte. Sind weitere Interrupts
möglich, wird die Reaktionszeit auch noch von der (zeitlichen) Länge
der anderen Interruptroutinen abhängig...

Input-Capture bedeutet natürlich, dass man genau diesen Anschluss
für Input-Capture nutzen muss.
Wenn du das nicht kannst, oder willst - dann geht es eben nicht
genauer. IST SO. FERTIG.

Ansonsten dachte ich, dass die Übertakterei seit ca. 20 Jahren
Kinderkram und out of fashion ist. Aber Dummheit stirbt nicht aus...
Wer nicht die simpelsten Regeln für flottes und exaktes Programmieren
drauf hat, schafft mit 24 MHz eher weniger, als andere mit 4...8 MHz.

von Anfänger (Gast)


Lesenswert?

S. Landolt schrieb:
> Falls PD6 und Timer2 frei sind: wie wäre es mit Input-Capture?

Könnte mir mal bitte jemand mit einfachen Worten erklären, wie 
Input-Capture funktioniert? Ich hab da noch nicht so den Durchblick :-(

von Stefan F. (Gast)


Lesenswert?

Anfänger schrieb:
> Könnte mir mal bitte jemand mit einfachen Worten erklären, wie
> Input-Capture funktioniert?

Der Zähler läuft mit einer festen Taktfrequenz durch (incl, Überläufen).

Ein externes Signal gibt den "Capture" Befehl. Dann kopiert der Zähler 
den aktuellen Zählerstand in ein Register und löst einen Interrupt aus. 
Die Software kann das Register dann in aller Ruhe auslesen.

Bei einem Frequenzzähler würdest du z.B. bei jeder steigenden Flanke 
capturen. Dann musst nur die biden gecapturten Zählerstände voneiannder 
subtrahieren.

von S. Landlt (Gast)


Lesenswert?

an Anfänger (& Bernhard S.):

Hier im konkreten Fall möchte Bernhard S. zwei Sekunden lang ankommende 
Impulse zählen; er benutzt dazu den Timer1 mit seinem Eingang T1 (= 
PB1). Problem dabei: er erzeugt die 2 s per Software und Interrupt, 
dabei entstehen  unterschiedlich lange Verzögerungen. Lösung: die 2 s 
per Hardware erzeugen, z.B. per Timer2 mit 'Toggle OC2A on Compare 
Match' - passenderweise ist dieser Ausgang OC2A gleichzeitig der Eingang 
ICP1 (Input-Capture) des Timer1. Bei einer Flanke an diesem Eingang wird 
ICR1 = TCNT1 gesetzt, und man kann den ausgelesenen Zählerstand 
weiterverarbeiten, ganz ohne Sorge um einzelne Takte bzw. verschiedene 
Latenzen - man hat ja (fast) alle Zeit der Welt (mehrere zehntausend 
Takte, um genau zu sein).

von S. Landolt (Gast)


Lesenswert?

(da hatte mir doch der Osterhase ein   o   geklaut)

Ganz konkret: Timer2 mit CTC auf OCR2A=250, bei Vorteiler 128, ergibt 
32000 Takte, bei Bernhard S.' 24 MHz werden für 2 s folglich 1500 
Durchläufe benötigt. Bei jedem Durchlauf wird noch auf eventuellen 
Überlauf von ICR1 geprüft, am Ende die Differenz gebildet - fertig: 
fortlaufende Messung (in aller Ruhe), bei minimaler 
Controllerauslastung.

von Stefan F. (Gast)


Lesenswert?

Wir haben hier zwei unterschiedliche Ansätze. Ich bezog mich im Beitrag 
Beitrag "Re: Problem 16Bit Timer auslesen und zurücksetzen für Frequenzzähler ATmega1284p Assembler" auf eine konstante 
hohe Taktfrequenz, wo die Takte zwischen zwei Flanken eines sehr viel 
langsameren Signals gezählt werden.

S. Landolt beschreibt den umgekehrten Weg, so das zu messende Signal den 
Takt liefert und dieser in einem festen Zeitfenster gezählt wird, das 
durch einen zweiten Timer vorgegeben wird. Dieses Verfahren eignet sich 
für hohe Frequenzen - passt hier also besser.

von S. Landolt (Gast)


Lesenswert?

Nun, Sie haben eine Periodenmessung (Reziprokzähler) beschrieben, aber 
für unseren Anfänger bleibt der Trick bei Input-Capture ja derselbe: 
bildlich gesprochen wird per Hardware eine Momentaufnahme der 
Zählerstandes gemacht.

von Stefan F. (Gast)


Lesenswert?

S. Landolt schrieb:
> Nun, Sie haben eine Periodenmessung (Reziprokzähler) beschrieben,
> aber für unseren Anfänger bleibt der Trick bei Input-Capture ja derselbe:
> bildlich gesprochen wird per Hardware eine Momentaufnahme der
> Zählerstandes gemacht.

Ja, das ist der gemeinsame Kern.

Von einem guten Frequenzzähler würde erwarten, dass er beide Verfahren 
unterstützt, so daß er auch niedrige Frequenzen (< 100 Hz bis weit unter 
1 Hz) mit zufriedenstellender Auflösung messen kann.

von Bernhard S. (bernhard)


Lesenswert?

Etwas Wasser muss ich trotzdem in den Wein gießen...

Input-Capture hat den Nachteil, dass zwei wertvolle Prozessor-Pins, 
welche auch nicht umprogrammierbar sind, geopfert werden müssen.

von c-hater (Gast)


Lesenswert?

Bernhard S. schrieb:

> Input-Capture hat den Nachteil, dass zwei wertvolle Prozessor-Pins,
> welche auch nicht umprogrammierbar sind, geopfert werden müssen.

Naja, nur wenn du zwei Kanäle messen willst, bei einem Kanal ist es halt 
nur ein Pin.

Und es ist ja ausserdem nicht so, dass der zusätzlich benötigt wird, 
sondern anstatt irgendeines anderen Pins, nämlich den, über den du im 
Moment dein zu messendes Signal einspeist. Dieser andere Pin wird ja 
dann frei.

von Bernhard S. (bernhard)


Lesenswert?

1.Pin Signaleinspeisung

2.Pin Input Capture

3.Pin Steuerung für Input Capture

Sind 3 Pins, momentan nur 1 Pin🤔

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Bernhard S. schrieb:
> 1.Pin Signaleinspeisung
>
> 2.Pin Input Capture
>
> 3.Pin Steuerung für Input Capture
>
> Sind 3 Pins, momentan nur 1 Pin🤔

Mir scheint, du hast die Sache nicht wirklich kapiert.

1. ersetzt du schlicht durch 2.
3. braucht man nicht, wozu soll das gut sein?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich dem TO einen Tipp geben darf. Aus dem Thread
Beitrag "Timer Overflow Counter - Wie richtig berücksichtigen?"
kannte bestimmt eine Menge passend zum Problem mitnehmen.

von Knut (Gast)


Lesenswert?

Was will er denn nun?

Erst wird gefragt, wie man Frequenz- und Zeiterfassung in einem
ATMega verbessern kann.

Klare Ansage: Hardware-Erfassung mit Input-Capture vermeidet alle
nicht vorher berechenbaren Interrupt-Verzögerungen.

Dann wird gequengelt, dass man sich Input-Capture erst mal anlesen
muss - und sich auch noch für den vorliegenden Fall eine
Programmier-Strategie ausdenken muss.

Dann wird ein Video gezeigt, in dem keine letzte Stelle wackelt,
obwohl darüber diskutiert werden muss! ... (?)

Dann wird gejammert, (offensichtlich ohne dass im Datenblatt
Input-Capture studiert wurde, oder gar die Anwendungsstrategie
überdacht wurde), dass damit plötzlich 3 mal so viele Pins benötigt
werden. - Was grundsätzlich schon mal Quatsch ist.

Selbst wenn: Genauigkeit gibt es nicht umsonst! Unter gegebenen
Bedingungen kostet es aber MANCHMAL nur etwas Flexibilität und
Gehirn-Einsatz...

Da fehlt nicht mehr viel am Troll

von S. Landolt (Gast)


Lesenswert?

Bernhard S. schrieb:
> 2.Pin Input Capture
>
> 3.Pin Steuerung für Input Capture

Sollte ich mich tatsächlich bei
> Falls PD6 und Timer2 frei sind ...
bzw.
> passenderweise ist dieser Ausgang OC2A gleichzeitig
> der Eingang ICP1 (Input-Capture) des Timer1
missverständlich ausgedrückt haben? Das täte mir leid.

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

c-hater schrieb:
> Bernhard S. schrieb:
>> 1.Pin Signaleinspeisung
>>
>> 2.Pin Input Capture
>>
>> 3.Pin Steuerung für Input Capture
>>
>> Sind 3 Pins, momentan nur 1 Pin🤔
>
> Mir scheint, du hast die Sache nicht wirklich kapiert.
>
> 1. ersetzt du schlicht durch 2.
> 3. braucht man nicht, wozu soll das gut sein?

Denke schon, dass Bernhard S. recht hat:

1. Ist die vom externen Teiler-FF kommende Frequenz (<= halbe 
CPU-Frequenz), die es zu messen gilt (an Pin T1 oder Pin T3).
2. Ist der Capture-Eingang (ICP1 oder ICP3) des hierfür verwendeten 
16-Bit-Counters.
3. Ist der Ausgang vom exakten 2-Sekunden-Timer (irgend ein OCxy).

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Der Capture-Mode geht bei ATmega1284 (und ATmega328 et al) leider nur 
mit einem 16-bit-Counter (nur für diesen gibt es einen ICP-Eingang), der 
aber andererseits auch sehr hilfreich wäre, um ein exaktes 
2-Sekunden-Capture-Signal zu erzeugen. Beides gleichzeitig geht nur bei 
ATmega1284 (zusätzlicher TCNT3, ebenfalls mit einem ICP-Eingang).

Doch für genaue Frequenzmessungen bis zur halben CPU-Frequenz geht es 
auch ohne Capture-Mode, sofern man einen präzisen Timer für die 2 
Sekunden Messzeit verwendet. Und das klappt eben möglichst einfach mit 
einem 16-Bit-Timer [1].

Allerdings muss der CPU-Takt dann wegen dem für exakte 2 Sekunden 
nötigen Vorteiler von 1024 ein Vielfaches von 512 sein (sonst die 
CPU-Frequenz ggf. per Trimmer auf ein Vielfaches von 512 justieren).

Wenn man für den 2-Sekunden-Timer TCNT1 verwendet, kann man genaue 
Messungen ohne Capture-Mode sogar mit einem ATmega328 durchführen.

Dann bleibt beim ATmega328 zum genauen Zählen aber nur noch ein 
8-Bit-Zähler, z. B. TCNT0, dessen Überlauf man dann per TOV-Interrupts 
in AVR-Registern akkumuliert, mit dem kleinen Nachteil, dass die 
Interrupts deutlich öfter auftreten. Aber man muss ja nur sehr wenige 
Befehle ausführen, nämlich 3 Register inkrementieren (und natürlich das 
Statusregister retten).

Beim ATmega1284 hat man den Luxus eines zweiten 16-Bit-Zählers. Falls 
dieser noch frei ist, wird die Angelegenheit wirklich sehr entspannt, da 
man deutlich seltener und nur zwei AVR-Register (oder ein 
Doppelregister) inkrementieren muss.

Damit wirklich kein Zählimpuls verloren geht (insbesondere nahe der 
halben CPU-Frequenz), wird man auch ohne Capture-Mode die 
Differenzmethode verwenden [2]: Messfrequenz = neuer Zählerstand minus 
alter Zählerstand, ohne Rücksicht auf die absoluten Werte.

Das ist selbst in Assembler-Spache eine einfache Übung.

Fazit: Das Messen von Frequenzen bis nahe der halben CPU-Frequenz geht 
per ATmega1284 (und ATmega328 et al) auch ohne Capture-Mode 100% exakt 
(ohne dass Zählimpulse verloren gehen), sofern man die Differentmethode 
verwendet.

[1] Ein exaktes 2-Sekunden-Capture-Signal mit einem 8-Bit-Timer zu 
realisieren, wäre einiges an Mehraufwand.

[2] Sonst verliert man bei Messungen nahe der halben CPU-Frequenz wegen 
getrennten Befehlen für Lesen und Löschen eines 8-Bit-Zählers im Mittel 
genau einen Zählimpuls, beim 16-Bit-Zähler entsprechend mehr.

von Oliver S. (oliverso)


Lesenswert?

Das Eingangssignal muß natürlich an den ICP-Pin.
1.) entfällt damit.
Und wofür soll 3.) sein?

Oliver

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Eberhard H. schrieb:
> Fazit: Das Messen von Frequenzen bis nahe der halben CPU-Frequenz geht
> per ATmega1284 (und ATmega328 et al) auch ohne Capture-Mode 100% exakt
> (ohne dass Zählimpulse verloren gehen), sofern man die Differentmethode
> verwendet.

Das kommt schlicht auf deine Definitionen von "genau" und "exakt" an. 
Wenn keine ISRs benötigt werden, und es auch sonst auf ein paar 
CPU-Zyklen mehr oder weniger nicht ankommt, geht das. Wenn nicht, dann 
nicht.

Oliver

: Bearbeitet durch User
von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> Das Eingangssignal muß natürlich an den ICP-Pin.
> 1.) entfällt damit.
> Und wofür soll 3.) sein?

1.) Bernhard S. misst nicht die Periodendauer, sondern zählt die an T1 
oder T3 anliegenden Impulse, nicht an ICP.

3.) Ist das exakte 2-Sekunden-Signal, denn für bis zu 20 MHz (und mehr) 
auf die letzte Stelle muss man eben 2 Sekunden lang zählen, wenn der 
halbierte Takt an T1 bzw. T3 anliegt.

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> Das kommt schlicht auf deine Definitionen von "genau" und "exakt" an.

Bernhard S. möchte es offensichtlich bis auf das letzte Bit genau.

Wie ich geschrieben habe, geht das auch ohne Capture-Mode (und mit 
Capture-Mode sowieso).

Aber ganz ohne Interrupts geht es zweifellos generell nicht.

von Oliver S. (oliverso)


Lesenswert?

Eberhard H. schrieb:
> Wie ich geschrieben habe, geht das auch ohne Capture-Mode

Das schriebst du.
Nur, schreiben kann man viel, wenn der Tag lang ist.

Also schreib doch mal, wie man auf einem AVR CPU-zyklengenau eine 
beliebige Zeit zwischen zwei Flanken messen kann, ohne den Capture-Mode 
zu benutzen.

Oliver

von Stefan F. (Gast)


Lesenswert?

Wer sagt denn, dass mal einen Interrupt verwenden muss, um das 
2-Sekunden Fenster abzustecken?

Wenn ich alle Interrupts sperre, kann ich Zeitspannen taktgenau mit 
Warteschleifen umsetzen.

* Timer auf 0 setzen
* exakt 2 Sekunden warten
* Timer auslesen

Wo ist das Problem?: Dass der µC in der Zwischenzeit nichts anderes tun 
kann. Das kann bei so einem Gerät durchaus akzeptabel sein.

von Oliver S. (oliverso)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wo ist das Problem?: Dass der µC in der Zwischenzeit nichts anderes tun
> kann. Das kann bei so einem Gerät durchaus akzeptabel sein.

Wenn du unter „Taktgenau“ wirklich auf genau eine Takt genau meins, will 
ich das sehen.

Die Befehle eines AVR brauchen nunmal unterschiedlich lang, und damit 
kann man immer ein- oder zwei Zyklen Abweichung in die Auswertung 
bekommen. In der Praxis spielt das bei zwei Sekunden Messzeit keine 
Rolle, aber „taktgenau“ im Sinne von „auf einen CPU-Takt genau“ geht 
halt nicht.

Oliver

: Bearbeitet durch User
von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Oliver S. schrieb:
> Die Befehle eines AVR brauchen nunmal unterschiedlich lang, und damit
> kann man immer ein- oder zwei Zyklen Abweichung in die Auswertung
> bekommen.

Du meinst vielleicht Befehle wie BRCC. Bei einer Schleife mit 100 
Wiederholungen braucht dieser Befehl genau 99*2 + 1 Takt. Daran ist 
nichts zufällig, alles ganz leicht im voraus berechenbar.

von Oliver S. (oliverso)


Lesenswert?

Ok, wir reden aneinander vorbei.

Ich rede von der Eberhard-Lösung mit einem externen 2-Sekundensignal, 
auf das er in Software ohne ICP taktgenau reagieren will.

Oliver

von Stefan F. (Gast)


Lesenswert?

Oliver S. schrieb:
> Ok, wir reden aneinander vorbei.
>
> Ich rede von der Eberhard-Lösung mit einem externen 2-Sekundensignal,
> auf das er in Software ohne ICP taktgenau reagieren will.

Ich dachte der Satz wäre klar gewesen:

Stefan ⛄ F. schrieb:
> Wenn ich alle Interrupts sperre, kann ich Zeitspannen taktgenau mit
> Warteschleifen umsetzen.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Momentane Lösung:

Halbierte Eingangsfrequenz taktet den 16Bit Timer1 (Zähler).

Der 8Bit Timer (Timer0) sorgt dafür, dass taktgenau alle 2 Sekunden 
der Timer1 ausgelesen wird, nach der Differenzmethode wird dann die 
Frequenz berechnet. Nebnebei noch Multiplex für LED, Drehgeber und 
Tasten abfragen, 1s Ausgang für Kalibrierung mit DCF-Signal usw.

Der 8Bit Timer (Timer2), als Control-Timer wird benötigt, um taktgenau 
die Frequenz auszulesen.

Bei 24Mhz Takt, jetzt könnt Ihr mich ruhig wieder prügeln, und 24MHz 
Eingangsfreuenz, werden exakt 24.000.000Hz angezeigt, nix geht 
verloren^^

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.