ATTiny85 Timer CTC kommt scheinbar nicht mit

    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!

    • Die ISR im ersten Post ist 10x länger mit Sichern und Rücksichern der Register beschäftigt als mit dem Umschalten des Pins. Und der Vorschlag das Ganze per Hardware zu machen ist der elegante Weg...
      Aus datenschutzrechtlichen Gründen befindet sich die Kontaktdaten auf der Rückseite dieses Beitrages.
    • Ob das Sichern und Restaurieren 10x länger dauert als das Toggeln des Pins ist nicht zwangsläufig der Grund, warum es nicht funktionierte.

      Vielmehr lag es an der Prozessorauslastung, warum es bei 1MHz Takt nicht funktioniert.

      Bei ISR-Routinen, die ohne NoSave aufgerufen werden, werden rund 56 Takte benötigt für den Einsprung und das Selbe nochtmal wenn die ISR verlassen wird. Das sind rund 120 Takte mit dem Toggeln von dem Pin.

      Um Die 8,7kHz am Ausgang zu erhalten, muss die ISR also mit der doppelten Frequenz aufgerufen werden.
      Also in der Sekunde 17400x. In Summe komme da pro Sekunde 17400 x 120 Takte = 2088000 Takte zusammen.

      Da der Prozessor jedoch nur mit 1MHz lief, kann man sich vorstellen, dass man da keine 8700Hz rausbekommt, sondern nur etwa die Hälfte.

      Die selbe Betrachtung bei 8MHz Systemtakt sieht da schon anders aus.
      Die Anzahl Takte für die ISR bleibt ja, wenn man 8700 Hz möchte.
      Aber mit 8MHz Systemtakt bekommt man eine Controllerauslastung von ca. 26%.
      Das klappt dann.

      Das zur Erklärung.

      Man hätte jetzt auch das NoSave verwenden können und nur das Register sichern und Restaurieren, welches beim Toggeln verändert wird.
      Dann hätte es wahrscheinlich auch mit 1MHz geklappt.
      Aber sobald der Code noch was anderes macht als nur die Takterzeugung gibts ein Jittern.
      Am Oszi könnte man das sehen. Das bedeutet die Frequenz würde etwas variieren.

      Der elegante Weg ist, wenn die Frequenz stabil sein soll, immer die Hardware zu nutzen. In diesem Fall also die Frequenz per Timer-Hardware erzeugen lassen. Dann würde sich die Frequenz auch nicht verändern, wenn der Code weitere Aufgaben erfüllt.

      Man hätte nun auch anstatt Pin Toggeln auch eine PWM verwenden können (Fast-PWM-Mode).
      Dabei hätte man auch die Pulsbreite einstellen können. Durch das Toggeln hat man aber die Gewissheit, dass das Puls/Pausen Verhältnis bei 1:1 liegt.

      Iim Lexikon gibts ein Tutorial zur Timerberechnung. Da wird das alles erklärt und beschrieben.
    • Nach Simulator und Hilfe werden 25 Register gesichert und wiederhergestellt.

      Zitat aus der Hilde PushAll: The saved registers are : R0-R5, R7,R10,R11 and R16-R31

      Hinzu kommt jedoch noch das Sichern/Restaurieren des Statusregisters sowie
      die Rücksprungadresse auf den Stack legen und wieder runter holen.

      In Summe braucht eine leere ISR, die ohne NoSave konfiguriert wurde 116 Takte.
      Enthalten ist dabei auch der Hin- und Rücksprung.

      Wollte man nun wissen, wie oft die ISR / Sekunde nun bei 1MHz Takt aufrufbar wäre,
      muss man den Systemtakt durch die Anzahl Takte eines ISR-Aufrufs teilen.

      In diesem Fall ist das 8620 mal. Das wäre dann eine MCU-Auslastung von 100%.

      Ist in der ISR z.B. "Toggle PortB.1" als Code angegeben,
      verlängert sich die Ausführungszeit der ISR um 2 Takte.

      Maximale ISR-Aufrufe / Sekunde wären dann 1000000 / 118 = 8474 mal. Die Frequenz am Toggle-Pin wäre damit theoretisch bei 4237Hz. Theoretisch deshalb, weil der interne Oszillator vermutlich nicht genau mit 1MHz läuft und deshalb abweichungen entstehen.

      Die Berechnung geht natürlich nur dann auf, solange keine weiteren Interrupts konfiguriert/auszuführen sind.

      Im Vergleich:

      Konfiguriert man die ISR mit NoSave und schreibt in die ISR folgenden Inhalt:

      BASCOM-Quellcode

      1. ISR_Test:
      2. 'If MyTimeout >= 1 then Decr MyTimeout
      3. !PUSH r24
      4. Toggle PortB.1
      5. !POP r24
      6. Return
      Dann benötigt die ISR komplett nur 16 Takte. Hierbei werden nur die Register gesichert, die verändert werden, nämlich das r24 Register. Das Statusregister wird nicht verändert und muss nicht gesichert werden. (Geprüft mit Simulator)

      Damit könnte die ISR bei 1MHz Takt maximal 62500 mal pro Sekunde aufgerufen werden (1000000 / 16). Das entspräche einer Ausgabefrequenz von 31250Hz.

      Fazit:
      Die Interrupt-Variante aus dem 1. Post hätte funktioniert, sofern man nur die Register gesichert hätte, die in der ISR auch verändert werden.
      Aber die Erzeugung der Frequenz per Hardware bleibt die bessere Variante.

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

    • Mitch64 schrieb:

      Ist in der ISR z.B. "Toggle PortB.1" als Code angegeben,
      verlängert sich die Ausführungszeit der ISR um 2 Takte.
      in der Tat, 2 Takte laut Simulator.
      Wie schafft der Chip das?
      Ich meine, der Port muss als Byte gelesen werden.
      Der Pin muss angeschaut werden und entsprechend gewechselt werden.
      Und das ganze zurückgeschrieben. Dabei müssen die Nachbarbits bestehen bleiben.

      Der Attiny13 oder ein Atmega 32 braucht hier übrigens 4 Takte.
      Ein Atmega328p (Nano oder Uno) hat wieder nur 2 Takte.

      Möglicherweise wird hier das Pin-Register benutzt, was bei älteren Chips nicht ging.
    • Ich weis nicht, welches PDF du meinst.
      Ich habe im Datasheet "atmega48p_88p_168p_328p.pdf" geschaut, welches von Bascom in den PDF-Ordner gedownloaded wird (PDF-Update).
      Und da steht es auf Seite 75, Überschrift 14.1.

      Aber du hast recht!

      Spoiler anzeigen

      Three I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, Data
      Direction Register – DDRx, and the Port Input Pins – PINx. The Port Input Pins I/O location is read only, while
      the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the
      PINx Register, will result in a toggle in the corresponding bit in the Data Register. In addition, the Pull-up Disable
      – PUD bit in MCUCR disables the pull-up function for all pins in all ports when set.


      Das PDF hätte ich gerne angehängt, aber es ist zu groß.
    • So, mein Quarz ist da. In der Wartezeit habe ich mir einen kleinen HV-Brenner auf Arduino-Basis gebastelt. Jetzt kann ich ruhig herum probieren, ich kann sie ja wieder "retten".

      Mitch64: Was hast du damit gemeint? (Die Einsen)

      Mitch64 schrieb:

      Ich empfehle auch die Einstellung mit den ganzen Einsen vor "Ext. Crystal", sofern kein driftiger Grund dagegen spricht.
      Der Controller muss ja nicht ultraschnell starten.
    • So, nach einigen Versuchen hat das "fusen" jetzt geklappt, aber das Ergebnis ist enttäuschend ungenau.
      Mit den Fuses:
      Divide clock by 8, OFF
      111111: Ext. Crystal Ost.
      und einem 11 MHz Quartz müsste ich bei meinem Programm mit OCR0A = 79 eine Frequenz von 8702,532 Hz heraus bekommen. Tatsächlich erhalte ich 8594 Hz.

      Ist der Quarz so ungenau?

      sind meine 2x 22p Kondensatoren vielleicht nicht passend?