Kein Timer0 Compare-Match-Interrupt bei ATmega328P möglich

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    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!

    • Kein Timer0 Compare-Match-Interrupt bei ATmega328P möglich

      Liebe Forenmitglieder,

      ich bin neu hier im Forum...leider, wie es meist so ist, wegen Fragen zu Startschwierigkeiten :)
      Normalerweise programmiere ich AVR-Controller mit C oder Assembler. Wenn es das Bastelprojekt zulässt, bin ich jedoch auch ein Fan von
      klassischer analoger Elektronik und verwende z.B. für Zeitangelegenheiten gerne mal das gute alte 555-Timer IC.
      Meine Nutzung von Microcontrollern ist eher selten, und auch wenn ich die kleinen Käfer schon seit bald 20 Jahren programmiere,
      ist es immer ein großer Akt, das Programm für den Controller zu schreiben, weil ich einfach nicht ständig in der Materie stecke.
      Mit Bascom erhoffe ich mir hier etwas Zeitgewinn und mehr Freude an Controller-Projekten...dann werden sie auch öfter genutzt :D
      Ich bin also gerade noch in der Lernphase...

      Nun zum Problem...kurz und knapp: Ich bekomme beim Timer0 keinen Interrupt bei einem Compare-Match zum laufen.
      Die Bascom-Hilfe verstehe ich eher so, dass der Timer0 diese Funktion nicht unterstützt. Auch liest man im Netz oft die Aussage,
      dass das der Timer0 nicht kann. Der ATmega328P kann das aber definitiv mit dem Timer0. Selbst der ATiny13A, den ich oft benutze, kann das.
      Hätte vielleicht jemand einen Tipp für mich, was ich falsch mache? Oder ob diese Funktion tatsächlich durch Bascom selbst eingeschränkt ist?
      Ich weiß, dass ich mit einer Preload-Alternative arbeiten könnte und auch, dass ich den Timer1 nutzen könnte (das geht übrigens)...mir geht es aber speziell
      um den Timer0.

      Hier mal ein Beispielcode von mir:

      BASCOM Source Code

      1. $Regfile = "m328pdef.dat"
      2. $Crystal=16000000
      3. $hwstack = 40
      4. $swstack=16
      5. $framesize = 32
      6. dim counts as byte
      7. config timer0 = timer , prescale = 64 , clear_timer = 1 , compare_a = disconnect
      8. ocr0a = 20
      9. enable oc0a
      10. on oc0a timer_isr
      11. enable interrupts
      12. do
      13. loop
      14. timer_isr:
      15. counts = counts + 1
      16. return
      Display All
      Ich habe schon sämtliche Varianten von "config timer" ausprobiert. Auch habe ich OCR0A gegen COMPARE0A getauscht...ebenso mit OC0A.
      Wenn ich die 0er durch 1er ersetze (also für Timer1), läuft alles einwandfrei :D

      Über Hilfe würde ich mich sehr freuen.
    • Hallo andisan und willkommen im Forum,
      wie stellst du bei dem geposteten Programm fest, dass es nicht läuft?
      Für mich sieht das korrekt aus und ja, der 328P kann den Compare0A .
      Die Bascom Hilfe unterscheidet nicht immer zwischen den älteren Typen (z.B. Mega8, der das nicht kann) und den neueren, wie dem Mega328P.
    • Hallo Andisan,

      ich hab mir erlaubt, Deinen Beispielcode um eine serielle Ausgabe zu erweitern, um die Timerinterrupts im Praxistest nachzuweisen (zugegebenermaßen quick&dirty).
      Die Interrupts werden ausgeführt.
      Wie Franz schon geschrieben hat, wäre es interresant zu wissen, wie Du das Nichtfunktionieren bei Timer0 und das Funktionieren bei Verwendung des Timer1 festgestellt hast.
      Vielleicht liegt ein Harwaredefekt bei Deinem Atmega vor? Schon mal getauscht?

      Nette Grüße
      Rob

      BASCOM Source Code

      1. $Regfile = "m328pdef.dat"
      2. $Crystal=16000000
      3. $hwstack = 40
      4. $swstack=16
      5. $framesize = 32
      6. $baud = 115200
      7. dim counts as byte
      8. Dim Temp_Count_1 as Byte
      9. Dim Temp_Count_2 as Byte
      10. config timer0 = timer , prescale = 64 , clear_timer = 1 , compare_a = disconnect
      11. ocr0a = 20 ' Interrupt alle 80us
      12. enable oc0a
      13. on oc0a timer_isr
      14. enable interrupts
      15. do
      16. Waitus 800 ' Nach 800us sollten 10 Interrupts erfolgt sein
      17. Temp_Count_1 = Counts ' Ergebnis sollte also "10" sein
      18. Waitus 800 ' Nach weiteren 800us sollten insgesamt 20 Interrupts erfolgt sein
      19. Temp_Count_2 = Counts ' Ergebnis sollte nun "20" sein
      20. Print "Temp_Count_1 = " ; Temp_Count_1 ' Ergebnis im Terminal beim ersten Programmdurchlauf "Temp_Count_1 = 10"
      21. Print "Temp_Count_2 = " ; Temp_Count_2 ' Ergebnis im Terminal beim ersten Programmdurchlauf "Temp_Count_2 = 20"
      22. Wait 5
      23. loop
      24. timer_isr:
      25. counts = counts + 1
      26. return
      Display All
    • Hallo Franz, hallo Rob,

      vielen Dank für eure Antworten.
      Tatsächlich habe ich das ganze lediglich im Simulator getestet. Da es auch mit AVR-Studio und besonders mit Atmel Studio bei einigen Controllern Simulationsprobleme mit Interrupts gibt, habe ich im Bascom Simulator auch mal verschiedene Controller durchgetestet, mit dem gleichen Ergebnis. Ich hätte eher gedacht, dass der Bascom Simulator besonders gut/zuverlässig ist, weil das gesamte Framework mit IDE aus einem Guss ist...aber dem ist leider nicht so, wie ich schon auch an anderen Stellen feststellen musste :(
      Das mit dem debuggen per UART wollte ich heute auch noch probieren, aber da kam mir Rob zuvor...danke hierfür ;)

      Dann bin ich jetzt erstmal zufrieden, dass es zumindest real funktioniert. Da ich normalerweise viel mit Interrupts arbeite, ist der Simulator natürlich nicht so der Hit. Um zumindest gewisse Zeiten/Zyklen der Anweisungen zu prüfen, bin ich hier auf einen guten Vorschlag gestoßen:
      Workaround: Interrupt im Simulator


      Franz wrote:

      Nur der Timer1 wird richtig simuliert, die anderen laufen dort überhaupt nicht.
      Der Interrupt für Überlauf an Timer0 hat bei mir sogar funktioniert...lediglich der Compare-Match-Interrupt klappte nicht. Deswegen dachte ich schon, dass Bascom das überhaupt nicht unterstützt, weil es in der Hilfe ja auch mehr oder weniger so verstanden werden kann.


      Also vielen Dank euch! Ich denke, das Thema wäre erstmal gelöst.
    • Ursprünglich wollte ich ihn in Schutz nehmen: Beim Mega8 gehen 5 von 7 :/
      Beim 328 auch nur 5 aber von 10. ;( So richtig übel wird beim 328pb da laufen timer 3 und 4 gar nicht los und selbst die Int Tasten erreichen teilweise die falschen Isr :cursing: Auch schlecht für Update Fans: Ab Version 2084 läuft auch der timer0 nicht mehr los a_28_2c02f089
      Auch merkt er sich keine Ints. sollte er in einem sein vergisst er weitere ;(
      Eine Behelfslösung könnte das sein:
      #if _sim=1
      if timer0 >=100 then gosub ocr0a_isr
      timer0=0
      #endif

      Eigentlich schade das sie ihn so stiefmütterlich behandeln, wo er doch in den meisten anderen Fällen sehr nützlich ist.

      PS Beim Timer 2 sind prescale 32 und 128 nicht richtig umgesetzt