Verständnissgrundlagen Timerberechnung

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Verständnissgrundlagen Timerberechnung

      Hallo Community,

      lange bevor ich ein Bascom-Projekt realisiere mache ich mir generell Gedanken zur Machbarkeit und des How-Do's. Genau an diesem Punkt bin ich gerade, weswegen ich noch kein Quelltext habe den ich einfügen könnte.

      Ich möchte gerne über den Timer1 eines AT-Megas Tonfrequenzen messen, indem ich die Zeit zwischen zwei Nulldurchgängen erfasse.
      Es geht um knapp 20 Tonfrequenzen zwischen 800Hz und 5kHz welche Halwellenabstände zwischen 625µs und 100µs aufweisen.
      Es ist zwingend vorrausgesetzt das jede Halbwelle eines Eingangssignals vermessen wird, unabhängig ob es eine steigende oder fallende Flanke ist, die wahlweise am ICP1 (über externen Komperator) oder über AIN0 (interner Komperator).

      Timer1 soll dann mit einer hohen Taktfrequenz (z.B. 16MHz) rauf zählen und bei jedem Pegelwechsel an ICP1 oder AIN0/1 in einer INT den aktuellen Zählerwert in eine Variable übergeben und genullt werden um erneut rauf zu zählen bis zum nächsten Pegelwechsel.

      Da tauchen aber zunächst zwei Fragen auf:
      Im Bascom-Handbuch finde ich zu "CONFIG TIMER1" die Funktionen "EDGE=Falling/Rising" und die Funktion "CAPTURE_EDGE=Falling/Rising"

      Beides passt nicht auf mein anliegen, wo fallende und steigende Flanke gleichwertig sein sollen.
      Wäre hier auch z.B. die Funktion "CAPTURE_EDGE=CHANGE" erlaubt?
      Ich finde weder bei Bascom noch im Internet eine klare Dokumentation dazu.

      Die nächste Frage wäre ganz ähnlich in der Thematik, betrifft aber die Zählgeschwindigkeit von Timer1:
      Wenn ich den via "PRESCALE=1" direkt mit den 16MHz des Taktquarzes befeuere, zählt er dann nur aufsteigende Flanken der Clock, oder je Schritt abfallende und steigende Flanken gleichwertig.

      Zählt er nur aufsteigende Flanken der Clock würde er bei 16MHz Takt alle 62,5ns herhöht.
      Zählt er fallende und steigende Flanke gleichwertig, würde er bei 16MHz alle 31,25ns hoch zählen.

      Heißt: im ersteren Fall würde der Timer1 alle 2,048ms überlaufen, im zweiteren Fall alle 1,024ms.

      Ich finde weder bei Bascom noch in den Datenblättern der AT-Megas dazu aufschlussreiche Hinweise.

      Wäre schön wenn mir hier jemand seine Erfahrungen dazu mitteilen könnte.

      Grüße

      Jürgen
    • Hi Jürgen, der timer zählt nur bei einer Flankenrichtung des Taktes, welche, weiß ich jetzt nicht.
      Wenn du bei einen pin-change den timer1 auslösen willst, kannst du ja auch int0/int1 verwenden. Mit dessen irs timer1 lesen. Das auf Null stellen, kannst du dir sparen, wenn dein zu messender Zeitabschnitt in die Zeitspanne passt, die der timer1 ohne Überlauf braucht. Wenn das der Fall ist, einfach letztgelesenen Timer1stand vom vorhergelesenen abziehen. Also Halbwelle beginnt und löst die isr aus, Timerstand lesen, beim nächsten Nulldurchgang Timerstand wieder lesen und voneinander abziehen.

      Da jetzt die isr recht ähnlich bei beiden Auslösungen ist, es braucht vielleicht noch ein flag, das nach dem Timerlesen gesetzt wird, spielt die Zeit, die das Aufrufen braucht keine Rolle und du erhälst einen genauen Wert für deine Halbwellenlänge.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • Hallo tschoeatsch!

      Ja, einen externen Komperator an int0 oder int1 zu hängen und als pinchange zu konfigurieren war auch meine erste Idee.
      Allerdings habe ich mich nach den durcharbeiten mehrerer AVR-Datenblätter irgendwie auf den ICP1 oder den AIN verbissen.

      Wenn aber diese beiden nur wahlweise steigende oder fallende Flanken zählen, bleibt mir wohl nur der Weg über int0/1

      Das mit dem löschen oder nicht löschen des Timer1-Wertes muss ich später gucken.
      Mir ist nicht klar wieviel Takte ich verschwende beim löschen des Timerwertes, oder alternativ bei der von dir vorgeschlagenen Aufaddierung und späterer Subtrahlierung oder auch Dreisatz-Berechnung wenn da ein Überlauf zwischen war.

      Wenn ich den Zählwert von Timer 1 halwegs Latenzarm (<10 Systemtakte) löschen kann, wäre das mein Vavorit, da ich dann bereits eindeutige Halbwellenwerte erhalte.

      Daher auch meine Frage ob der Zähler im Takt einer oder beider Flanken der Clock zählt.
      Davon hängt ab ob der Timer knapp 1ms oder 2ms erfasst.
      Nach deiner Auskunft komme ich jetzt bei befeuerung mit 16MHz auf einen Überlauf alle 2,048ms überlaufen.

      Die längste zu messene Halbwelle wird bei 625µs liegen, die da durchaus dreifach rein passt.
      Egal, halte mir erst mal beide Ansätze vor.

      Mein Anspruch soll sein genau zu erfassen wieviele Halwellen nit welcher Frequenz erfasst wird.
      Beispielsweise in einer Kette von z.B. 100 Halbwellen mit 179µs (2400Hz) eine einzelne Halbwelle mit 104µs (4800Hz) sicher erkennen. Stichwort FFSK/MSK/GFSK-Auswertung durch Halbwellenvermessung.

      Grüße

      Jürgen
    • Hallo Jürgen,

      bei 16 MHz dauert eine Taktperiode 62,5 ns, und nach jeweils 65536 Takten läuft der Timer1 über, d.h. bei einem Prescaler von 1 alle 4,096 ms (62,5 ns * 65536). Soviel zur Überlauf-Zeit.

      Auch wenn Du den Timer nicht nach jeder Flanke zurücksetzt, sondern ihn einfach durchlaufen lässt, brauchst Du keinen "Dreisatz", wenn er zwischen zwei Flanken übergelaufen ist. Ein kleines Beispiel: Bei der niedrigsten Frequenz dauert die Periode (wie Du geschrieben hast) 625 µs, der Timer zählt also genau 10.000 Schritte weiter. Wenn Du vom aktuellen Wert den jeweils vorherigen Wert abziehst, passiert folgendes:

      1. Halbwelle: 10000 - 0 = 10000
      2. Halbwelle: 20000 - 10000 = 10000
      ...
      6. Halbwelle: 60000 - 50000 = 10000
      7. Halbwelle: 4465 (nach weiteren 10.000 Schritten und einem Überlauf!) - 60000 = 10000

      Die letzte Zeile scheint vielleicht etwas unlogisch, aber da Words nicht negativ werden können, passiert ein "Rückwärts-Überlauf" auch dann, wenn man von einem kleineren Word ein größeres subtrahiert. 10 - 20 wäre auf Word-Ebene z.B. 65525.

      Täusche ich mich, oder klingt das nach einer AFu-Anwendung?

      Grüße,

      Daniel (DL6MCL)
    • Da sind ja jetzt die Funker beieinander und ich versteh' wieder nur Bahnsteig. Ist das verwand mit Tonwahl? Tonhöhe entspricht einem Zeichen?
      Ich empfinde die Vorgabe, nur eine Halbwellenlänge zu messen als Fehlerquelle. Der Nulldurchgang ist ja am Anfang der Halbwelle und am Ende verschieden (Vorzeichen der Steigung der Kurve, mal banal ausgedrückt). Eine Elektronik, die den Nulldurchgang erkennt, liefert doch nur ein 'ungefähr jetzt wäre ein Nulldurchgang'. Dieses 'ungefähr' würde ich vom Wert her als unterschiedlich ansehen, wenn man steigenden, bzw fallenden Kurvenverlauf hat. Aber, diese Befürchtungen entspringen meinem Viertel- (Halb-, Dreiviertel-?) Wissen.
      Könntest du die zu messende Frequenz nicht einfach gleichrichten?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Nochmal ich. Wenn du die Vollwelle betrachten würdest, wäre ja der Nulldurchgang schnurz. Ein Sinus an einem Digitaleingang liefert Rechteck und die Flanken mit gleicher Richtung haben Vollwellenabstand. Dann bräuchtest du doch nur ein Standardfrequenzmessprogramm nehmen und fertig ist die Frequenzerkennung. Wenn du gleichrichtest, dann ist es doch das gleiche, nur dass du doppelte Frequenz angezeigt bekommst, was du halt entsprechend interpretieren musst. Ok, wenn du eine ungerade Anzahl von Halbwellen geliefert bekommst, wird's schon komplizierter (gefühlsmäßig).
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • DG7GJ schrieb:


      Wenn aber diese beiden nur wahlweise steigende oder fallende Flanken zählen, bleibt mir wohl nur der Weg über int0/1
      Du löst doch einen Interrupt aus und in dem kannst du die Erkennung der Flanke auf die jeweils andere umschalten. Dazu hast du bei deinen niedrigen Frequenzen alle Zeit.

      Du solltest den Timer Wert nicht manuell ändern, besonders nicht, wenn du mit Prescale < 64 arbeitest. Der Timer zählt ja weiter genauso wie auch die Zeit für deine Halbwelle weiterläuft. Änderst du jetzt seinen Wert (nullen) kommt am Ende ein Fehler raus, da der Aufruf der ISR mit Sicherung aller Register ~60 Takte benötigt. Also hat der Timer bei Prescale 1 schon mindestens 60 weitergezählt, wenn du ihn löschst.
    • Es ist ja egal, wielange es dauert, bis auf den timer-Wert zugegriffen wird, wenn es nur am Anfang der Halbwelle genau so lange ist, wie am Ende der Halbwelle. Man hat aber nur eine isr, die beim Start der Messung und am Ende der Messung aufgerufen wird. Darum muss man dafür sorgen, dass das jeweilige Bearbeiten des timers, ob nullen oder lesen, an der gleichen zeitlichen Stelle innerhalb der isr passiert.
      Wenn die Messzeit die timerlaufzeit (0..Überlauf) nicht überschreitet, muss man sich nicht um einen Überlauf kümmern. Egal, ob man vom 0 los zählt, oder die Differenz Endstand-Startstand bildet.

      @DG7GJ wie schaut dein Protokoll aus? Nur 2 Töne? Wieviele Halbwellen in der Summe, bis eine Pause kommt? Kommt eine Pause überhaupt? Und wie und wann werden die Daten (Tonhöhe und Halbwellenzahl) weiter verarbeitet?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • tschoeatsch schrieb:

      Es ist ja egal, wielange es dauert, bis auf den timer-Wert zugegriffen wird, wenn es nur am Anfang der Halbwelle genau so lange ist, wie am Ende der Halbwelle.
      Das ist doch gerade der Vorteil, wenn du den ICP benutzt, dass du dann von solchen Unwägbarkeiten unabhängig wirst.
      Sonst kommt dir Irgendwann eine andere ISR dazwischen und schon bist du weit weg von gleicher Zeit am Anfang wie am Ende. Für mich ist das vollkommen unnötige Murkserei.
    • Guenther schrieb:

      Das ist doch gerade der Vorteil, wenn du den ICP benutzt, dass du dann von solchen Unwägbarkeiten unabhängig wirst.
      da hast du Recht, nur es ist ja die Vorgabe eine Halbwelle zu messen und es wird dazu offenbar eine Flanke beim Nulldurchgang erzeugt, die die Richtung wechselt. ICP triggert nur bei gleichen Flanken, also Vollwelle.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ok, hatte ich irgendwie überlesen oder nicht gerallert.
      Aber hab' ich das richtig verstanden: eine passende Flanke am ICP-pin kopiert den timerstand, und das ohne isr. Ich brauch dann noch eine isr, um das bit zu toggeln und auch um zu wissen, das ein timer-Stand auszulesen ist. Wer löst die aus, auch ICP?
      Edit: natürlich ICP.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von tschoeatsch ()

    • Hallo!

      Vielen Dank für die Antworten, die mich schon mal deutlich weiter bringen.

      @ Einzeller:
      Danke für deine bestätigung das der Timer bei 16MHz in 62,5ns-Schritten läuft, also Überlauf nach 4,096ms.

      Was deine Rechenbeispiele angeht zum Thema Subtraktion der vorherigen Werte trotz Überlauf...das ist mir noch nicht absolut klar.
      Werde ich mal manuell verschiedene Überlauf-Beispiele die denkbar sind durchrechnen.
      Stelle mir da die Notwendigkeit einer Routine vor die immer dann wenn ein Meßergebniss kleiner als das vorherige ist, die Differenz des Vorwertes zum Überlauf zum neuen Wert hinzuaddiert.

      Was deine Frage angeht zum Thema AFU-Anwendung: Thematisch Artverwand, ziele aber nicht auf AFU.
      Sprich: Sowas wie BELL202/AX.25 habe ich noch nicht in meinem Plichtheftchen, wäre aber hypotetisch problemlos auch mit einpflegbar wenn es mal läuft.
      Ich arbeite Beruflich gelegentlich mit FFSK-Modems die alle mit CMX469 oder MSM6948 (OKI) arbeiten.
      Mit den Vorüberlegungen hier versuche ich ein Modem (genauer: Vorerst Auswerter, später vielleicht auch Geber) auf Basis der Flankenvermessung zu eruieren, welches eben nicht auf die 1200/2400/4800Bd-FFSK-Standards festgenagelt ist.
      Also neben FMS, DigiS und BIIS z.B. noch den krummen 1024Bd-Standard der Personenruf- und Grundstucksfunkanlagen (1024Hz / 1536Hz) erschlägt.

      Im Endeffekt geht es um eine Reihe von FFSK-Verfahren welche vorwiegend ausserhalb des Amaterufunkes präsent sind.
      Der Ursprung dieser Idee basiert auf diese Datensammlung von mir:
      funktechnik-hueser.de/TMPdat/FFSK/Infopaket-Datenfunk.rar


      @ tschoeatsch:

      Das da speziell am Anfang und am Ende eines Datenpaketes Müll ist, ist logisch. In der Realität können sogar innerhalb eines Datenpaketes Müllwerte auftauchen, eben weil das Signal über Funk empfangen wird und der Rauschabstand nicht durchweg optimal sein kann.
      Daher muss da selbstverständlich eine Logik hinter, welche genau guckt ob ein Meßwert nun gültig ist oder nicht.
      Das ist ein mehrschichtiges Entscheidungssystem wo es am Beginn egal ist was da für Müllwerte angeht, sondern ob der nachfolgende Meßwert passt.

      Kleines Beispiel...FFSK nach 1200Bd-Standard besteht aus 1,0 Perioden (2 Halbwellen) 1200Hz für logisch bin1 und 1,5 Perioden (3 Halbwellen) 1800Hz für logisch bin0.
      Der Timer müsste also ab Beginn eines Datenpaketes das Dotting (simple 010101-Folge) messen:
      2x 417µs gefolgt von 3x 278µs hintereinander.

      Da erkennst du nun auch weswegen ich alle Nulldurchgänge vermessen muss.
      Statt 2x417µs und 3x278µs in Nulldurchgängen sähe es bei Perioden schon nach Pfusch aus: 1x834µs + 1x556µs (+1x278µs die nach nachfolgende Bit verfälscht).

      Noch deutlicher wird die Notwendigkeit auf Nulldurchgangsebene zu messen bei höheren Baudraten:
      2400Bd-FFSK arbeitet mit 0,5 Perioden (1 Nulldurchgang) 1200Hz für logisch "1" und 1,0 Perioden (2 Nulldurchgänge) 2400Hz für logisch "0".
      4800Bd-FFSK arbeitet mit 0,5 Perioden (1 Nulldurchgang) 2400Hz für logisch "1" und 1,0 Perioden (2 Nulldurchgänge) 4800Hz für logisch "0".

      Um innerhalb eines Datenpaketes saubere Nulldurchgänge zu erhalten, braucht man freilich einen gut dimensionierten Komperator, und davor auch noch einiges an Signalkonditionierung.

      Zu deiner Frage ob es nur um zwei Töne geht, und um die Summe der Halbwellen zu einer Pause:
      Ich erkenne was hinter deine Frage steht...kurz und knapp: Nein, kein einziges Protokoll welches ich anstrebe passt mit einem einzelnen Datenpaket in den Timer von schlappe 4,096ms. Es sind zu 90% alles Protokolle die mit Datenpaketlängen zwischen 100 und 600ms liegen, wo also innerhalb des Datenpaketes bis zu 146 Timerüberläufe liegen können, die rausgerechnet/korrigiert werden müssen. Bei all diesen FFSK-Geschichten ist es eher selten das eine Reihe idetischer Werte übertragen werden...statt 0000000-Phasen ist eher üblich 0101100101110 und so weiter.

      Insgesamt sollen bisher vier Baudraten mit jeweils zwei spezifischen Einzeltönen automatisch erkannt werden:
      1536Hz + 1024Hz = 1024Bd FFSK
      1200Hz + 1800Hz = 1200Bd FFSK
      1200Hz + 2400Hz = 2400Bd FFSK
      2400Hz + 4800Hz = 4800Bd FFSK/GFSK

      Anschließend soll im binären Datenstrom die Wortsynchronisation (Startwort) gesucht und anhand dessen das jeweilige Protokoll erkannt werden, um den nachfolgenden Bitstrom dann passend zum verwendeten Protokoll (momentan etwa 8 Protokolle, werden aber noch mehr) dekodieren und die zum Protokoll gehörende Fehlerüberprüfung (teils Parity, überwiegend aber BCH-System mit CRC) angewendet werden.

      @Guenther
      Das mit den Latenzen beim nullen des Counters habe ich befürchtet, konnte mir aber nicht vorstellen wie viele Takte dafür draufgehen.
      Daher danke ich dir für deine Angabe von "~60 Takte" die ich mir als Richtwert mal so notiere.

      Interessant finde ich aber deinen Hinweis am ICP einfach in jeder ISR die Flankenauswertung zu toogeln.
      Das hört sich für mich vielversprechend an, allerdings kann ich mir noch nicht ausmalen zu welchen Effekten das mitunter führt.
      Daher mal eine Überlegung:

      Oben vor der Programmschleife konfiguriere ich den Timer so das er bei einem Low-High-Wechsel den ISR auslöst.
      In der ISR muss ich nach dem Auslesen des Timerwortes dann direkt den Timer umstellen auf High-Low-Wechsel.
      Solange der Wert an ICP noch High ist, sollte ein Wechsel der Auswerterpolarität selber keinen ISR auslösen...OK...
      In der ISR aber darf ich diese Änderung aber sicher nicht mit einem kompletten Config Timer1 machen, sondern müsste eher manuell das entsprechende Register ändern.
      Mal gurz das Datenblatt konsultieren...
      Ahja...das müsste Bit 6 des Registers TCCR1B sein...

      Grübel...könnte man mit ner Bit-Variable "CPol" irgendwie so machen nach dem auslesen des Timers:

      toogle CPol
      TCCR1B.6 = CPol
      return

      Sollte das einfachste sein...danke für den Hinweis!

      Jürgen
    • Ich, wenig wissend, frag' nochmal nach: nach deiner Signalaufbereitung und dem Komparator hast du ein Signal, das bei jedem Nulldurchgang toggelt. Den zeitlichen Abstand des toggelns misst du mit dem timer. Damit hast du die Frequenz der Halbwelle. Was machst du jetzt mit diesem Wissen, es folgt ja gleich die nächste Halbwelle. Erst die Summe dieser Einzelerkenntnisse kann man doch dann für eine genauere Auswertung durcharbeiten. Wenn du schreibst, es kann viel Mist ankommen, kann man die einzelnen erkannten bits nicht einfach aneinander reihen. Das ist jetzt eigentlich meine Frage gewesen, wieviele Halbwellen kommen ohne Pause hintereinander und wann und wieviel Zeit hat man dann zur Auswertung? Ich könnte mir jetzt das nur so vorstellen, dass nach jedem Nulldrchgang, in der Zeit bis zum nächsten, die Frequenz berechnet wird und in einem Puffer zwischengespeichert wird. Wenn dann mal Sendepause herrscht, wird dieser Pufferinhalt analysiert.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------