AVR Counter Interrupt

Gast #4877619
Lesenswert?

Hi,

ich nutze einen Timer als Counter. Gezählt wird der Quarz über einen 
Prescaler, um einen niedrige Frequenz möglichst genau zu messen. (aufs 
hz genau)

Ich nutze den overflow interrupt, wenn der timer vollgelaufen ist um 
intern die überläufe zu merken, und später zum timer hinzuzuaddieren. 
soweit kein problem. Momentan macht das eine schleife im hauptprogramm 
die den timer startet und stoppt und dann den timer ausliest. Dazu muss 
ich aber den avr bei 16mhz laufen lassen, damit das abfragen des 
Takteingangs schnell genug ist. ich habe bereits bei 8mhz deutliche 
messschwankungen)

Gibt es eine möglichkeit das zB nach zwei fallenden flanken der zähler 
gestoppt und dann ein Interrupt ausgelöst wird? (also wenn man den timer 
als counter betreibt?)
Gast #4877626
Lesenswert?

Hallo Basti,

was zählt bei Dir die externe Frequenz ?
a) ein Hardwarezähler oder
b) das Programm ?

Es gibt verschiedene Messverfahren, i.a. liegt die max. zählbare 
Frequenz bei ~ Takt der CPU / 2.5, ohne Vorteiler.
Gast #4877632
Lesenswert?

Basti schrieb:
> Gibt es eine möglichkeit das zB nach zwei fallenden flanken der zähler
> gestoppt und dann ein Interrupt ausgelöst wird? (also wenn man den timer
> als counter betreibt?)

Ja per Software in Verbindung mit einem "Hardware" Interrupteingang geht 
das immer, natürlich benötigt das Erreichen einer ISR auch einige 
Taktzyklen, bis dann der relevante Code ausgeführt werden kann.

Zeige bitte dein komplettes Programm.
Gast #4877640
Lesenswert?

Hi,

timer0 zählt die 16mhz der CPU bei einem 8er prescaler

die zu messende frequenz liegt zw 0-1000hz

die hauptschleife wartet auf low pegel und startet den timer
wenn der pegel das nächste mal auf 0 geht wird der timer gestoppt und 
der timerwert und die gemerkten überläufe aufaddiert und die frequenz 
berechnet. Es wäre aber ser schön wenn das starten und stoppen des 
timers in hardware zu realisieren ginge

do
loop until speed_in=0 'Wait for input low
enable timer0
start timer0
timer0=0
   do
   loop until speed_in=1
   do
   loop until speed_in=0
stop timer0
counts=256*timer0_ov  'variable aus dem überlauf interrupt
counts=act_counts+timer0 'gezählte rest kommt hinzu
duration=duration_8*counts 'mit der impulsdauer multiplizieren 
(1/16Mhz*8)
freq=1/duration
#4877822
Lesenswert?

Basti schrieb:
> die hauptschleife wartet auf low pegel und startet den timer
> wenn der pegel das nächste mal auf 0 geht wird der timer gestoppt und
> der timerwert und die gemerkten überläufe aufaddiert und die frequenz
> berechnet.

Du machst also in Wirklichkeit eine direkte Periodendauermessung deines 
Eingangssignals.

Das ist im Detail maximal ungeschickt. Es besteht keine Notwendigkeit, 
den Timer zu stoppen oder auf 0 zu setzen. Einfach bei jedem Wechsel des 
Eingangssignals von H auf L den Timer auslesen und die Differenz zum 
Timerwert beim vorigen Mal bilden. Der Timer läuft dabei einfach durch 
und der Überlaufzähler wird einfach wie ein höherwertiges Wort des 
Timers betrachtet.

Also z.B. 16-Bit Timer (in Hardware) + 16-Bit Überlaufzähler ergibt 
einen 32-Bit Zähler. Damit kannst du bei 8MHz Quarzfrequenz bis 0.002Hz 
Eingangsfrequenz messen. Gleichzeitig hast du bei 1kHz Meßfrequenz noch 
8000 Ticks entsprechend 0.125Hz Auflösung.

Wenn du jetzt das Signal nicht in einer Endlosschleife abfragst, sondern 
einen Interrupt dafür nimmst, dann wird das noch genauer.

> Es wäre aber ser schön wenn das starten und stoppen des
> timers in hardware zu realisieren ginge

Dann lies mal das Kapitel über die Capture-Einheiten der Hardware-Zähler 
im AVR.

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