"genaues" stellen einer RTC (asynchron TIMER2)?

    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!

    • "genaues" stellen einer RTC (asynchron TIMER2)?

      Hallo!

      Derzeit stehe ich bei einer simplen herrausforderung auf dem Schlauch.
      Es geht darum eine asynchrone 32kHz-Clock am Timer2 zu setzen, und zwar genauer als 1s.

      Habe es zunächst wie folgt versucht:

      BASCOM-Quellcode

      1. SetRTC:
      2. Stop Timer2
      3. _Year = Jahr
      4. _moth = Monat
      5. _day = Tag
      6. _hour = Stunde
      7. _min = Minute
      8. _sec = Sekunde
      9. TCNT2 = 51 'Startwert in 3,9ms-Auflösung
      10. Start Timer2
      11. Return
      Alles anzeigen

      Das Ergebnis: Der Stop Timer2 in Zeile 3 funktioniert tadellos.
      Der Start Timer2 in Zeile 14 wird aber offensichtlich ignoriert.

      Rahmenbedingungen:
      ATmega324PA @ 3,3V mit interner RC-Clock @ 8MHz als Haupttakt. Timer2 mit dem 32kHz-Quarz dient nur der RTC.

      Wenn ich Zeile 3 und 14 auskommentiere, gelingt es mir nicht wirklich alleine mit TCNT2-Vorgabe (Zeile 12) den Sekundenübergang genauer zu bestimmen.
      Egal ob ich dort 0, 50, 100 oder 200 setze...das Ergebnis ist immer eher zufällig und +-1s.

      Würde mir eher wünschen das ich die Zeit zum nachfolgenden Sekundenwechsel beim stellen genauer definieren kann.
      Nur durch beschreiben des Registers TCNT2 scheint das gerade nicht zu funktionieren. a_56_df238249

      Grüße

      Jürgen
    • setz' den timer nach dem Stoppen mal auf 0. Durch das stop wird nicht weiter gezählt, ein Zählerstand bleibt erhalten und wird beim Start berücksichtigt.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • war jetzt Quatsch. Der timer sollte ja noch einen prescaler haben, damit ein Sekundentakt generiert wird. Den müsste man auch setzen.
      • Bit 1 – PSRASY: Prescaler Reset Timer/Counter2 When this bit is one, the Timer/Counter2 prescaler will be reset. This bit is normally cleared immediately by hardware. If the bit is written when Timer/Counter2 is operating in asynchronous mode, the bit will remain one until the prescaler has been reset. The bit will not be cleared by hardware if the TSM bit is set. Refer to the description of the “Bit 7 – TSM: Timer/Counter Synchronization Mode” on this page for a description of the Timer/Counter Synchronization mode.
      Ich würde mal damit rumprobieren :huh: Screenshot_2020-05-25-17-36-11-409.jpeg
      Raum für Notizen

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

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

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

    • Hallo tschoeatsch,

      Der Timer2 wird im Hauptprogramm ganz normal mit Config Clock = Soft initialisiert.
      Hierdurch wird durch Bascom automatisch gesetzt:

      TCCR2B = &b00000101
      ASSR = &b00100000

      Also Vorteiler auf 128: 32768 Quarz / 128 = 256Hz
      Der TCNT2 wird also mit 256Hz befeuert womit sich eine Wertigkeit von ca. 3,9ms je Bit ergibt.
      Diese Schrittweite würde mir absolut reichen zur Feineinstellung - es geht mir eher darum bei Setzung der neuen Zeit die RTC im Bereich einiger dutzend ms "vor" zu stellen.

      Also anders gesagt:
      Start Timer2 bis zur nächsten Sekunde 800ms, danach gewöhnlich wieder 1000ms.

      Laut Datenblatt des ATmega324PA soll TCNT2 ohne den Counter zu stoppen beshreibbar sein, unter der Berücksichtigung das der neue Wert erst zwei Zählimpulse später gesetzt wird (ca. 8ms später).

      Aber wie bereits angedeutet: Egal was ich für einen Wert in TCNT2 schreibe, es gelingt mir dadurch nicht den Beginn der nachfolgenden Sekunde genauer zu definieren.
      Aber ich stricke gerade schon ein Testaufbau um mal am Oszi zu gucken ob das Lable überhaupt zu einer definierten Zeit angesprungen wird.
    • naja, der prescaler ist ja ein Zähler, der hat ja auch einen 'Stand', wenn du den timer setzt. Setzen dieses Zählers geht wohl nicht, aber zurück setzen geht. Nach einem reset startet der prescaler bei 0 und nach 127 Quarzticks tickt der timer2 eins weiter. Dadurch sollte es immer mit definierten Werten starten und so immer eine definierte Restzeit geben. Allerdings sind 128/2^15 s die maximale Abweichung, wenn nicht resettet wird. Ob das so spürbar ist a_27_b277ca12 Mir fällt aber nix besseres ein.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Mitch64 schrieb:

      Gibts da nicht ein Bit in einem Register namens Prescaler-Reset?
      siehe Beitrag von mir weiter oben PSRASY

      djmsc schrieb:

      tschoeatsch schrieb:

      der prescaler ist ja ein Zähler
      Das ist so nicht ganz richtigt. Prescaler = Vorteiler.
      und wie teilt der? Bei einen prescale von 128 wird bis 128 gezählt, um einen Takt weiter zu geben und dann mit 0 wieder mit dem Zählen begonnen...
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • tschoeatsch schrieb:

      und wie teilt der?
      Meißt eine Reihe Flip Flops die durch 2 teilen. Mit dem Prescaler wird dann ausgewählt ob der Eingang, der 3. , 6. , 8. oder 10. Ausgang als Timertakt benutzt wird. Da ist nichts was eine Vorgabe/Reset machen könnte.
      Nun sind aber die ca 4ms nicht sein Problem sondern das der Timer keine neuen Wert annimmt während er zählt obwohl das im Simulator kein Problem ist.
    • @Pluto25 freilich gibt es einen reset, siehe post#3. Das dieser reset nicht die fette Wirkung hat, hab ich ja auch schon vermutet.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Grübel....ich dachte man könnte mich erhellen und nicht noch mehr verwirren...
      Oder was soll die idee mit Precounter resetten?

      Die Asynchrone RTC basiert IMMER und Überall auf folgendem Gundsystem:

      Ein 32,768kHz Uhrenquarz an TOSC1 und TOSC2 sowie dem Timer 2 entsprechend gesetzt als asynchroner Timer und Precounter /128.
      Der Vorteiler sorgt dafür das die Quarzfrequenz 32,768kHz /128 geteilt = 256Hz auf den 8Bit-Timer 2 geht.
      Dieser zählt nun mit 256Hz aufwärts und läuft daher alle 256 Impulse über - immer im Übergang hFF zu h00.
      Dieses löst den Sectic aus.

      Will ich nun die Uhr exakter stellen, geht das m.E. nur über das setzen eines entsprechenden Wertes im TCNT2 - also das Timer-Register welches von h00 bis hFF zählt.
      Aber bestimmt nicht durch resetten des Vorteilers.

      Ung wundern tue ich mich weniger um die wiederspenzigkeit den Wert in den TCNT2 zu bekommen, sondern primär daran das die Zeile 14 in meinem Quellcode "Start Timer2" nicht funktioniert.
      Zu Beginn "Stop Timer2" geht wunderbar, aber Start Timer2 zum Schluß macht nix.
      Nach stellung der RTC läuft sie schlichtweg nicht mehr an.
    • Um Von 32768 Hz auf 1 Hz zu kommen bedarf es den Prescaler (geteilt durch 128) plus den Zähler mit 8 Bit (geteilt durch 256).
      Daher muss man den Zäher und den Prescaler zusammen auf 0 setzen. Also Prescaler resetten und den Zähler.
      Nur das eine oder andere macht wenig Sinn. Wenn eine Sekunde gerade beginnt, puss ja Prescaler und TCNT2 0Null sein.

      Warum aber der Timer2 nicht mehr anläuft, wenn der Zählerwert geändert wird weiß ich so auch nicht.
      Entweder wird durch schreiben in das TCNT2-Register der Asynchron-Mode vom Timer2 deaktiviert oder die Werte für Timer2 Konfiguration werden verändert.
      Ich würde mal den Simulator bemühen und schauen, was der da sichert mit "Stop Timer2", und was der wieder restauriert mit "Start Timer2".

      Ich meine mich zu erinnern, dass mit Stop Timer das Register, in dem der Prescaler-Wert steht, gesichert wird.
      Start Timer2 müsste also dieses Register wieder herstellen.

      Einfach mal im Simulator schauen, was steht in den Timer-Registern drin bevor Stop Timer2 aufgerufen wird, und was steht nach Start Timer2 drin.
      Vielleicht gibt's da einen Unterschied, was ich jetzt mal vermute.
    • Hast du denn gar kein Config Timer2=Timer in deinem Programm?
      Ich hätte einen Befehl wie
      Config Timer2=Timer, Prescale=128, Async=On erwartet.
      Stop Timer setzt den prescale=0 (in dem entsprechenden Timer Register), sodass der Timer nicht mehr läuft. Der aktuelle Zählerstand bleibt dabei erhalten.
      Start Timer setzt den Prescale auf den Wert im Config Befehl. Wenn jetzt keiner in deinem Programm ist, könnte es sein, dass Start Timer den Prescale nicht setzen kann.

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

    • Da der @DG7GJ kein ordentliches Codeschnipsel bereit gestellt hat, habe ich mir selber was gebastelt, um den Sachverhalt zu testen.

      BASCOM-Quellcode

      1. $regfile = "m324padef.dat"
      2. $hwstack = 40
      3. $swstack = 40
      4. $framesize = 60
      5. $Crystal = 8000000
      6. Dim Jahr as Byte
      7. Dim Monat as Byte
      8. Dim Tag as Byte
      9. Dim Stunde as Byte
      10. Dim Minute as Byte
      11. Dim Sekunde as Byte
      12. Dim StoreTimer2 as Byte
      13. Config Clock = Soft ' Uhr Konfigurieren
      14. StoreTimer2 = TCCR2B
      15. Macro Start_Timer2
      16. TCCR2B = StoreTimer2
      17. End Macro
      18. Enable Interrupts
      19. Do
      20. Gosub SetRTC
      21. Loop
      22. SetRTC:
      23. Stop Timer2
      24. _Year = Jahr
      25. _month = Monat
      26. _day = Tag
      27. _hour = Stunde
      28. _min = Minute
      29. _sec = Sekunde
      30. 'TCNT2 = 51 'Startwert in 3,9ms-Auflösung
      31. 'Start Timer2
      32. Start_Timer2 ' TCCR2B restaurieren
      33. Return
      Alles anzeigen
      Nach obigem Code sollte der Timer2 nach Stop Timer2 wieder laufen.
      Problem ist offensichtlich der Befehl Start Timer2, der die Konfiguration nicht wiederherstellt.
      Daher habe ich ein Macro verwendet Namens Start_Timer2.

      Zur Erklärung.

      Config Clock = Soft
      konfiguriert den Timer 2, genauer gesagt wird in das Register TCCR2B = $05 reingeschrieben, was dem Prescaler 128 entspricht.
      Auch TIMSK2 = 1 wird konfiguriert, was hier aber keine Rolle spielt.

      Mit Stop Timer2 wird Das Register TCCR2B = 0 gesetzt. Damit steht der Timer2, da er keinen Takt bekommt.
      Der Befehl Start Timer2 schreibt in das Register TCCR2B = 0 rein. Der Timer2 läuft also nicht wieder an, so wie @DG7GJ bereits im Post #1 gesagt hat.

      Ob das nun ein Bug ist, oder ob das vom Entwickler beabsichtigt ist, kann ich nicht sagen.
      Aber man kann sich behelfen, wenn man das Register TCRC2B selber sichert, nachdem die Uhr konfiguriert wurde (siehe Zeile 18), aber bevor ein Stop Timer2 ausgeführt wird.
      Und es dann selber wieder restauriert (siehe Zeile 45). Man kann das auch ohne Macro machen.

      Aber selbst wenn jetzt der Timer wieder anläuft, kann man die Sekunden trotzdem nicht genau stellen.
      Mal wird es funktionieren, mal nicht. Das höngt vom Zählerstand ab.

      Ach so. Das setzen des Zählers hat nichts damit zu tun, dass der timer nicht mehr anläuft.

      Ich habe das jetzt alles im Simulator getestet.