Hallo. Ich möchte mithilfe meines Atmega 8 µC ein Rechtecksignal mit ca. 500 khZ auswerten. Es handelt sich bei meinen Versuch um einen berührungslosen Sensor, der seine Frequenz vermindert, wenn man sich mit den Finger zur die Sensorfläche nähert. MFG
Es gibt im Forum, in der Codesammlung und auch hier http://www.mikrocontroller.net/articles/AVR_Softwarepool unzählige Beiträge zum Thema Frequenzmessung. Welche hast du denn schon studiert?
Möchstest Du dazu C oder Assembler benutzen? Soll es über Timer-IRQ im Hintergrund laufen? Grüße Heiko
Ich habe es mit diesem Quelltext versucht, jedoch ich konnte nur Frequenzen zwischen 0 und 50 khz ohne Probleme auswerten, alles was darüber ist, funktioniert nicht mehr richtig. Liegt es vielleicht am atmega 8?
Ich würde Assembler bevorzugen. Ich versteh nicht ganz, was mit dem Timer im Hintergrund gemeint ist...
wiss schrieb: > Ich habe es mit diesem Quelltext versucht, jedoch ich konnte nur > Frequenzen zwischen 0 und 50 khz ohne Probleme auswerten, alles was > darüber ist, funktioniert nicht mehr richtig. > Liegt es vielleicht am atmega 8? Wie schnell taktest du den? Die Messung am INTO wird irgendwann schlapp machen. Aber die Messung am Input Capture sollte mit 500kHz eigentlich noch so lala klar kommen. Allerdings denke ich, dass in dem Code noch Fehler sind. Ich konzentriere mich jetzt nur auf den Input Capture.
1 | ISR( TIMER1_CAPT_vect ) |
2 | {
|
3 | static unsigned char ErsteFlanke1 = TRUE; |
4 | |
5 | if( Update1 && Update0 ) |
6 | return; |
ändern auf
1 | ISR( TIMER1_CAPT_vect ) |
2 | {
|
3 | static unsigned char ErsteFlanke1 = TRUE; |
4 | |
5 | if( Update1 ) |
6 | return; |
-------------------------------- Die Overflow Behandlung ist auch nicht korrekt. Etwas abhilfe (auch wenn es noch nicht ganz korrekt ist), würde bringen:
1 | Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1; |
ändern auf
1 | if( NumberOverflow1 > 1 ) |
2 | Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1; |
3 | else
|
4 | Erg1 = EndTime1 - StartTime1; |
Woran machst du fest, dass die Ergebnisse nicht stimmen?
Im übrigen ist das Messprinzip in beiden Fällen hier die Messung der Periodendauer. Diesem Messprinzip ist es zu eigen, dass die Messauflösung schlechter wird, je höher die Frequenzen werden. Bei deinen Frequenzen (wie weit geht die Frequenz eigentlich runter, wenn der Sensor anspricht), wäre wahrscheinlich eine Zählung der Pulse in einer Torzeit besser geeignet (da wird die Messauflösung schlechter, je niedriger die Frequenzen werden)
Karl heinz Buchegger schrieb: > Die Overflow Behandlung ist auch nicht korrekt. Etwas abhilfe (auch wenn > es noch nicht ganz korrekt ist), würde bringen: > Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1; Hallo Karl Heinz, könntest du mir erklären, wieso das nicht korrekt ist? Ich sehe darin keinen Fehler (aber ich täusche mich wohl) und möchte nun dazu lernen :-) Danke.
Marc schrieb: > könntest du mir erklären, wieso das nicht korrekt ist? Ich sehe darin > keinen Fehler (aber ich täusche mich wohl) und möchte nun dazu lernen Weil die Differenz zweier unsigned Werte in diesem Fall auch bei 1 Overflow das korrekte Ergebnis bringt. Erst wenn ein zweiter Overflow dazukommt muss man handeln. Wobei auch das noch immer nicht korrekt ist, wenn ich es mir recht überlege Die Logik muss sein: 1 Overflow wird ignoriert, wenn Ende kleiner als Start ist. Ist Ende größer/gleich stimmt die Anzahl der Overflows. Probiers einfach mit kleineren Zahlen durch Sagen wir Start und Ende können nur Werte von 0 bis 7 annehmen. Start sei zb 5 jetzt geben wir dazu noch 4 Zählticks dazu Start 5 (Tick 1) 6 (Tick 2) 7 (Tick 3) 0 <- Hier gibt es den ersten Overflow (Tick 4) 1 Wir haben also Start: 5 Ende: 1 Anzahl Overflows: 1 unsigned gerechnet: Ende - Start: 1 - 5 macht 4 Overflows: 1*8 macht 8 ------ 12 d.h. so gerechnet, würde bei der Messung rauskommen, dass 12 Ticks gezählt wurden. Wir hatten aber nur 4. 1 Overflow wurde zuviel eingerechnet Jetzt das ganz mal mit 9 Ticks vom Start bis zum Ende Start: 5 (Tick 1) 6 (Tick 2) 7 (Tick 3) 0 <--- Hier ist der erste Overflow (Tick 4) 1 (Tick 5) 2 (Tick 6) 3 (Tick 7) 4 (Tick 8) 5 (Tick 9) 6 Unsere gemessenen Kennzahlen sind also: Start: 5 Ende: 6 Anzahl Overflows: 1 ausgewertet ergibt das Ende - Start: 6 - 5 macht 1 Overflows: 1*8 macht 8 ------ 9 Jetzt stimmt die Rechnung. Dieser 1 Overflow darf nicht ignoriert werden. Das Kriterium ist, ob Ende größer/gleich Start ist. Ist das der Fall, dann stimmt die Anzahl der Overflows und muss eingerechnet werden. Ist das aber nicht der Fall (wie im ersten Beispiel) dann wurde zwar ein Overflow detektiert, der sich aber durch die unsigned Rechnung nicht auswirkt. Wir müssen also mit 1 Overflow weniger rechnen. (Das ganze dann natürlich sinngemäs hochskaliert, wenn mehrere Overflows auftauchen)
1 | if( EndTime1 < StartTime1 ) |
2 | NumberOverflow1--; |
3 | |
4 | Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1; |
Wenn du dir leichter tust, dann stell dir eine Uhr vor (damit sind wir vertrauter). Wieviele Sekunden sind vergangen, wenn der Sekundenzeiger von 55 bis 12 gelaufen ist? Genau. Der Sekundenzeiger ist zwar über die 60 drübergelaufen (und hat damit 1 'Overflow' registriert), aber das spielt hier keine Rolle, es sind trotzdem nur 17 Sekunden vergangen. Ist der Sekundenzeiger aber von 15 ... tick, tick, tick, über die Minute drüber, tick, ... bis 20 gelaufen, dann sind das 65 Sekunden und der eine Overflow über die 60 Sekunden drüber wirkt sich aus.
Danke Karl Heinz, ich habe nun verstanden, was daran falsch ist. Vielen Dank nochmal.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.