PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zählfehler über INT0



kleinstar
06.05.2007, 16:44
Hallo,
ich möcht mit dem Mega 32 frequenzen im MHz-Berich messen, hab auch schon bissi Plan wie man den Timer einsetzt. ...

Wenn der Int0 ausgelöst wird (auf GND ziehen) zählt der Zähler in der IRQ gleich um 10 bis 50 stellen weiter.. wie kann ich dass verhindern?(Pullup? Interner Pullup?wie groß sollte dieser sein? wieviel mA kann man da rein geben: mit I=5V/R...und so):

Enable Interrupts
Enable Int0
Config Int0 = Rising
On Int0 Irq

Irq:
Incr Flankenzahl
Schreibe "irq zähler"
Return

den Timerteil hab ich hier nich rein geschrieben...

-ist es egal, an welche stelle man diesen code schreibt (zb in Sub hinein)?

-unterbricht der Int0 , wenn er enabled ist an jeder stelle das Prog und springt zu seiner IRQ?(kann man dass mit disable int0 abschalten?)

Ich hoffe , dass das nicht zu viele Fragen sind und dass das nich unverschähmt ist...Aber ich finde immer nie klare Antworten oder Stichpunktzettel von diesen Algorithmen...
Ich danke schonmal dem, der mir in dieser Verzweiflungsstunde helfen mag;)!
der Roland

PicNick
06.05.2007, 17:36
"auf GND ziehen" und "int0 = rising" is irgendwie genau das gegenteil.
However:
1. diese "schreibe irq zähler" wird in der Interrupt routine sicher zu lange dauern, wenn du flottere Inpulse zählen willst.
2. Beim Testen erzeugst du beim "auf GND ziehen" wahrscheinlich grauenhafte Impulsformen, die eigentlich "debounced" werden müßten.
das ist also eher ein Fehler der Test-konfigration.
Die Impulse müssen "saubere" Flanken haben.

3. Ins MHZ-Bereich wirst du so nicht kommen, daß schafft der arme Mega nicht.
Schau dir mal die "Counter" Konfiguration an, da geht einiges mehr als so.

kleinstar
06.05.2007, 18:34
Dankeschön für die Antwort..
klar macht schon sinn mit falling...
kann man eigentlich definieren, dass ich nicht auf masse ziehe um einen Impuls zu machen, sondern auf 5V? wie sagichs meinem MC..
..dann werd ich mir erstmal den Counter reinziehn, was man damit machen kann.
Ich hatte es ja so angedacht, dass ich mit nem timer ein zeitfenster mach und in der zeit, bis zu seinem IRQ die impulse zähle um dann daraus die Pereodendauer auszurechnen..
hat vielleicht jemand schonmal sowas gemacht? wo man sich ein paar anregungen holen könnte?
danke für die Antwort und Deine Zeit!
der Roland

linux_80
06.05.2007, 19:46
Hallo,

Du könntest Dir beim Timer die ICP Funktion angucken, hier kann man den Timer, bzw. dann Counter, bis zur nächsten Flanke zählen lassen, der Counter schreibt automatisch den Wert in ein extra Register, damit man etwas Zeit hat, das auszulesen. Es kann auch ein IRQ ausgelöst werden, in dem man dann den Wert verarbeitet.

Ausschnitt mit Timer1 beim Mega32, so jetzt nicht getestet, nur zusammenkopiert :

$hwstack = 40
$swstack = 40
$framesize = 40

$regfile = "M32def.dat" ' the used chip
$crystal = 16000000 ' frequency used
$baud = 9600

Config Timer1 = Counter , Capture Edge = Falling , Prescale = 256

Config Portd.6 = Input ' ICP1 Eingang
Portd.6 = 1

' Array und zähler für Timerdaten
Const Maxcapt = 60
Dim Capt(maxcapt) As Word
Dim Ccnt As Byte

On Icp1 Icp_isr
Enable Icp1

' Reset IC IRQ
Tifr.icf1 = 1
Enable Interrupts

Do
' Reset IC IRQ
Stop Timer1
Timer1 = 0
Capture1 = 0
Tccr1b.ices1 = 0
Tifr.icf1 = 1
Ccnt = 0

Start Timer1
Enable Icp1

' warten bis array voll
While Ccnt < Maxcapt
Wend

Disable Icp1

' Ausgeben
For X = 1 To Maxcapt
Print Capt(x)
Next X

Wait 2

Loop

' Capture IRQ
Icp_isr:

Timer1 = 0
Toggle Tccr1b.ices1

' bis max. MaxCapt, dann nix mehr einlesen !
If Ccnt < Maxcapt Then
Incr Ccnt
Capt(ccnt) = Capture1
End If

Return
Das Programm sollte 60 Wechsel messen und in einem Array sammeln, danach per UART ausgeben.

kleinstar
12.05.2007, 18:26
hi,
danke für deinen code, bin den grad am durchmachen und versteh ihn schon ganz gut,
weiß nur nich so recht was diese zeilen bedeuten:
Tifr.icf1 = 1
Tccr1b.ices1 = 0
Toggle Tccr1b.ices1 und wieso toggle (heißt doch umschalten..)

tschuldigung wennich vielleicht zu blöd grad bin, aber weiß nicht wofür die sachen stehen und wie sie vielleicht erklärt sind..
Danke schön!!

linux_80
12.05.2007, 18:36
Um zu erfahren was das bedeutet sollte man schon das entsprechende DB daneben liegen haben, sonst kann man ja nicht programmieren ?! ;-)

gibts bei Atmel:
http://www.atmel.com/dyn/products/devices.asp?family_id=607
hier den Mega32 suchen, und dann das (umfangreichere) Datenblatt auf der Seite runterladen. Ab S.107 wirds dann interessant.

Toggle bedeutet umschalten, wollte ich ja auch so erreichen, einmal 0 dann wieder 1.

kleinstar
12.05.2007, 18:59
dankeschön,
puh, da kommich ja nich alleine drauf, hab mir das datenblatt geloded..
das sind register
timer interrupt flag register..
puh das is alles auf englisch, krass... da mussich ma irgedwo weiter auf deutsch nach ner anleitung rumsuchen, bisher gings ja auch ohne dieses Blatt;)
ich danke Dir auf jeden!

linux_80
12.05.2007, 19:06
In deutsch wirds das nicht so direkt geben, ausser Du findest ein Wiki, das dieses behandelt.

Also mit Tccr1b.ices1 wird eingestellt welche Richtung einer Flanke einen Capture auslöst, deshalb muss man das jedesmal umdrehen (mit toggle) damits beim nächstenmal in die andere Richtung auslöst.

Tifr.icf1 ist das IRQ Flag, das man mit =1 löscht, falls schon ein IRQ ansteht, und die Messung verfälschen würde.

kleinstar
12.05.2007, 19:45
hi,
na krass,
ich dachte man stellt mit capture =falling die flanke ein (brauch zum freq. messen eig. nur eine...da könntich das weglassen.hmm)

also wenn icp ausgelöst wird, dann löst das die icp_isr auf und im array wird ein Wert gewpeichert...und der Timer wird auf null gesetzt,
aber ich dachte, das während der isr der Timer nicht mehr weiter zählt.. dann würde ein Fehler entstehen und die Zeiten verfälscht.. oder ist dem nicht so?
Ich danke Dir abermals für Deine Zeit und Gedult mit mir!

linux_80
12.05.2007, 20:04
Für eine normale Frequenzmessung kann man das Toggle weglassen.
Ich hab das bei mir verwendet, weil ich damit das IR-Signal von Fernbedienungen aufgenommen habe, und da braucht man beide Richtungen.

Der Timer zählt immer weiter, deshalb gibts die Capture-Funktion, da wird beim erkennen der Flanke der Timer-Wert in das Capture-Register übertragen, und kann in Ruhe ausgelesen werden.
Ich stelle den Timer dann wieder auf 0, damit ich nicht auch noch rechnen muss (neuer Wert minus alter Wert usw.), wenn man den weiterlaufen lassen würde !
Je nach Prescaler kann es aber sein, das bis zum erreichen der Zeile in dem der Timer auf 0 gesetzt wird, dieser schon weitergezählt hat, diesen Fehler muss man evtl. in Erfahrung bringen und den Timer nicht auf 0 sondern einen höheren Wert setzen !
Bei mir wars egal ob der Wert eins mehr oder weniger hatte.

robbifan
13.05.2007, 13:16
grundvoraussetzung ist das datenblatt, ansonsten kannste das ganze proggen lassen. es gibt kein deutsches datenblatt für die avr. anhand der c-beispiele kann man es auch gut erkennen.

mfg

kleinstar
14.05.2007, 20:18
hi
iche wieder, der Frequenzheini..
Hey Linux 80,
hab ma das Capture prog umgebaut und im labor probiert..geht aber leíder nich..
es liegt am Zählen, die weiteren Berechnungen klappen prima, wenn ich die Capture Werte vorgeb...
wennich mir die meine 10 Array Werte ausgeben lass (also die gecapturten Timerstände),da kommen ganz komische Werte raus:
bei 1mhz zu messender Frequenz (Zähler müsste 16 sein)
kommt mal 4 , 0, 156..
das heißt er zählt bei kleine werten zu oft und bei großen vergisster manche Flanken...
ich messe mit 62,5ns pro zählschritt.. 16mhz durch 1.
am Oszi ham wir ganz komische Eingangspegel gesehen, mit überschwingen und so...
bei welchen Schwellen denn der icp1 eingang?
vielleicht captured er zu oft werte, weil die schwelle genau im überschwing bereich liegt..hmm
kann man da was einstellen.. vielleicht die schwellenhöhe oder sowas.
LG Roland

linux_80
14.05.2007, 21:07
Von einstellen (ausser der Richtung) weiss ich nix, aber es sollten halt schöne Flanken sein, und nicht zu schnell, weiss jetzt allerdings nicht wie es mit dem timing aussieht, also wann der Timer diese Flanken kennt.

Man kann aber, je nach AVR, den Analog-Comparator zum auslösen einstellen (statt ICP1), hab es aber jetzt nicht so ganz fertig gelesen. 8-[

Welche Frequenz wolltest du messen ?

kleinstar
15.05.2007, 17:33
hi,
na es ging bei keiner Frequenz richtich, weder 1mhz noch 10khz..
bin ja verwundert, dass Du's diesmal nich weißt:)!
nee, zerbrich Dir nich weiter den Kopf, ich machs jetz doch anders..
nehm ein zeitfenster und zähl mitm int0 die Flanken, wenn der Timer überläuft, quasi die zeit abgelaufen is, werden interrupts und der eingang disabled....
verzählt sich aber bei 2000 flanken um 4 oder so.. is aber schon recht gut findich..mussich aber noch innen griff kriegen (dürfte nur um +- eine Flanke schwanken, je nachdem , wie das zeitfenster grade zu den Flanken liegt..)
wenns dich interressiert schickich Dir den Code..aber ich denk du weißt schon wie, gelle
aber ich danke dir vielmals für Deine helfenden Worte und den Code auf jeden auch...
Grüße Roland