-
Zählfehler über INT0
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
-
"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.
-
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
-
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 :
Code:
$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.
-
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!!
-
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/de...?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.
-
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!
-
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.
-
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!
-
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.