Bug bei Timer0 PWM-Generierung?

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

    • Bug bei Timer0 PWM-Generierung?

      Hallo

      Timer0 scheint ein Problem zu haben bei der PWM-Generierung.
      OC0A-Pin sollte einen kurzen positiven Puls liefern und OB0B einen negativen.

      Mit Timer2 funktioniert das tadellos.

      Ich verwende die aktuelle Version 2.0.8.2.
      Als Fehlerquelle kann ich das File "m168def.dat" und auch die aktuelle "mcs.lib" ausschließen. Mit Bascom 2.0.8.1 habe ich das gleiche Problem.

      Kann jemand von euch bestätigen, dass mit folgendem Programm an beiden Ausgabepins das gleiche raus kommt? Also jeweils neg. Puls?
      Das wäre dann falsch.

      Ich denke mit einen Mega 44, 88 oder 328 sollte sich der Effekt auch zeigen.

      BASCOM Source Code

      1. ' Generierung einer 8-Bit PWM
      2. $Regfile = "m168def.dat"
      3. $Crystal = 8000000
      4. Wait 1
      5. ' PWM mit Timer0 fehlerhaft
      6. ' Frequenzausgabe an OC0A und OC0B
      7. ' OCnA Pins werden automatisch als Ausgang konfiguriert
      8. Config Timer0 = PWM , Prescale = 1 , Compare_A = Clear , Compare_B = Set , Clear Timer = 1
      9. 'Reset TCCR0A.COM0A0
      10. 'Reset TCCR0A.COM0B0
      11. OCR0A = 5 ' Tastverhältnis einstellen
      12. OCR0B = 5 ' Tastverhältnis einstellen
      13. Do
      14. NOP
      15. Loop
      Display All

      Ich habe herausgefunden, dass die Bits wie in Zeile 11 und 12 angegeben falsch gesetzt werden. Wenn ich die einzeln von Hand lösche, bekomme ich auch eine Änderung der PWM, nicht aber, wenn ich Compare_A oder Compare_B mit Set oder Clear konfiguriere.

      Mitch64
      Kaum macht man es richtig - und schon geht's!

      The post was edited 2 times, last by Mitch64 ().

    • Mitch64 wrote:

      wie es gesetzt sein sollte
      Richtig. Bei Compare_a=Clear müßte Com0a1 gesetz1 werden und com0a0 nicht (bzw gelöscht) Nach dem Einschalten sind sie alle 0 = Pin als normaler I/O nutzbar.


      tschoeatsch wrote:

      das clear timer=1
      Es setzt Wgm01. Und damit den Pwm fast (Mode 3) ohne wäre es Pwm Cor. (Mode 1)


      Ist ein Match Treffer nötig oder reicht ein Überlauf?
      Wie wäre der Pin bei:
      ocr0b=5
      Set timer0=30
      start timer0
      wird der Pin dann schon gesetzt oder erst nach 230 Clocks

      The post was edited 1 time, last by Pluto25 ().

    • Ok, wenn der timer genullt wird, dann doch bei seinem top-Wert, den man mit einem compare-Register einstellt. Dann bringt es doch nix, wenn man den dazu passenden Ausgang verwendet, es bleibt doch nur der andere übrig, an dem dann die pwm anliegt. Und das auch nur, wenn man vernünftige Werte in den Registern einträgt, gleiche Werte für beide wäre nicht vernünftig.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Hallo

      Ich danke euch allen für die Hilfestellungen und Tips.
      Mark hat mir mitgeteilt, dass es ein alter Bug zu sein scheint.

      Und er hat außerdem die gleiche Konfiguration wie @Guenther erwähnt.

      Guenther wrote:

      die Config muss so lauten:
      Config Timer0 = Pwm , Pwm = On , Prescale = 1 , Compare_a_pwm = Clear_up , Compare_b_pwm = Clear_down
      Deine ist ein Mix aus PWM und CTC Konfiguration.
      Das ist nicht ganz richtig. Die Konfiguration kann so lauten, muss aber nicht.
      Wenn die anderen Parameter Compare_A=Clear und Compare_B=Set funktionieren würden. Ist ja ein Bug, der irgendwann behoben wird.
      Und es ist kein Mix aus PWM und CTC-Mode. Es ist eine normale 8-Bit Fast-PWM. Der TopWert ist $FF.


      tschoeatsch wrote:

      Ich hab' mich auch über das clear timer=1 gewundert, das macht bei pwm doch keinen Sinn.
      Doch macht es. Es hat einfluss auf eines der WGM-Bits. Damit kann man zwischen normalen PWM-Mode (Phase Correct) und Fast-PWM Mode umschalten.

      Kurz erklärt:
      Bei Phase Correct zäht der Timer von 0 bis zu seinem TopWert und dann Rückwärts wieder bis 0 (Dual Slop). Die PWM macht also 2x256 Schritte für einen Durchlauf.

      Schaltet man mit Clear Timer=1 die FastPWM ein, wird nur von 0 bis zum Top-Wert gezählt. Dann wieder von vorne (Single Slop).
      Mit Clear Timer=0 kann man übrigens die FastPWM wieder in die PhaseCorrect PWM schalten.

      Übrigens habe ich an beiden Kanälen für die OCR0A und OCR0B den gleichen Wert angegeben, weil ja eigentlich ein Kanal invertiert sein sollte.
      Wegen dem Bug hat das aber nicht funktioniert.

      Aber mit der neuen Variante funktioniert es jetzt prima.

      Danke nochmal für eure Unterstützung.
      Kaum macht man es richtig - und schon geht's!
    • Klar, deswegen heißt die Option auch "Clear Timer" (on Compare Match) weil man damit Fast-PWM einschaltet.
      Du kannst das natürlich machen, aber wundere dich nicht, wenn der Compiler in der nächsten Version die Kombination PWM und Clear_Timer als Fehler zurückweist.
      Es sind beim normalen PWM übrigens nur 510 Schritte für einen Durchlauf.
      Compare_A ist halt für CTC und Counter, während Compare_A_PWM für PWM verwendet wird.
      Die möglichen Werte der Optionen sind unterschiedlich.
      Das dabei evtl. die gleichen Bits gesetzt werden, kann schon sein, muss aber nicht.
    • Guenther wrote:

      Es sind beim normalen PWM übrigens nur 510 Schritte für einen Durchlauf.
      Compare_A ist halt für CTC und Counter, während Compare_A_PWM für PWM verwendet wird.
      Die möglichen Werte der Optionen sind unterschiedlich.
      Das mit den 510 Schritte bei PhaseCorrect PWM ist mir neu. Klingt aber irgendwie plausibel. Das muss ich mir mal genauer ansehen. Das wäre dann mal eine neue Erkenntnis.

      Das mit Compare_A für CTC-Timer und Compare_A_PWM für reine PWM macht logisch betrachtet auch einen Sinn. Wieso bin ich da nie selber drauf gekommen?
      Also nich eine neue Erkenntnis.

      Vielen Dank für die Erklärung @Guenther
      Kaum macht man es richtig - und schon geht's!
    • Mitch64 wrote:

      Wieso ist das nicht einheitlich?
      Historische Gründe?
      Wenn man so was programmiert, dann hat man nicht immer gleich die Syntax vom letzten mal om Kopf.
      Später wurde es nicht mehr korrigiert, weil die Programme mit der unterschiedlichen Syntax geschrieben wurden.
      Ich kann mich noch gut an das Geschrei erinnern, als bei PWM was geändert wurde (ich glaube es war die Up/down Geschichte)
    • Michael wrote:

      Historische Gründe?
      Da scheint mir die Erklärung von @Guenther plausibler zu sein.

      Ich gebe dir aber Recht, wenn sich was am Syntax ändert, dass dann gerne gejammert wird.
      Aber seit Version 1.11.8.5 bin ich schon dabei. Wenn sich eine IDE weiter-entwickelt, geht das nicht immer ohne Änderungen am Syntax - verständlicherweise.

      So habe ich das erlebt mit dem Syntax für Inline-Assembler. Früher ging ohne das Ausrufezeichen vor der Assembleranweisung.

      Aber das ist ja kein Problem. Ich hatte mal ein altes Programm ausgegraben, welches solche alten Anweisungen drin hatte.
      Der Compiler meckert und man korrigiert es. Was kein Akt.

      Sonst sind mir keine gravierenden Änderungen bezüglich Syntax aufgefallen. Also solche, dass der Compiler durchdreht ;) .

      Wegen dem PWM wäre das eigentlich für künftige Bascom-Einsteiger eine Erleichterung.
      Selbst ich, alter Hase, mache seit 10 Jahren mit Bascom rum, muss feststellen, dass ich nicht den Unterschied zwischen Compare_A und Compare_A_PWM kannte.

      An dieser Stelle dürfte die Bascom-Hilfe ruhig etwas aufschlussreicher sein.

      Aber, man lernt nie aus.
      Kaum macht man es richtig - und schon geht's!
    • Jetzt noch mal zur pwm. @Mitch64 in deinem Programm aus post 1 erwartest du ja Signale, es soll der Ausgang umgeschaltet werden und das bei beiden, nur mit veränderter Phase. Die compare-Register haben beide denselben Wert wie der top, es gibt also beit top ein match und die Ausgänge werden gesetzt und bei bottom wird wieder zurück gesetzt. Das ergibt doch einen Nadelimpuls, sonst gäbe es ja auch kein Signal. Wie ist das, wenn das match bei 0 ist, also bottom? Gibt es immer Nadelimpulse? Das wäre ja dann nie 0% bzw 100% Einschaltdauer.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Es war ja auch eine Herausforderung den Timer mit seinen 13? Pwm Modes in einem Config unterzubringen. Das ganze noch fast selbsterklärend.
      Sie lassen sich auch mischen . Das würde den Bug umgehen:
      Config Timer0 = Pwm , Prescale = 1 , Compare_a_pwm = Clear_up , Compare_b = Set , Clear Timer = 1


      tschoeatsch wrote:

      Die compare-Register haben beide denselben Wert wie der top
      Mode 3: Top = $FF. Beide werte 5:
      Pin OCR0A=1 bis 5 dann 0 bis Top, und Pin OCR0B=0 bis 5 dann 1 bis Top

      The post was edited 1 time, last by Pluto25 ().

    • tschoeatsch wrote:

      Oder bin ich jetzt ganz gaga?
      Das ist das mit der Hilfe was Mitch ansprach. Eigendlich würde ich auch so erwachten . In den Registern sieht man was wirklich passiert.
      Mode 2,5 und 7 würden den Wert von Ocra als Top nehmen. Aber wie nun Basom klargemacht werden soll was er als Top nehmen muß ist mir auch nicht klar. In solchen Fällen schreibe ich gleich die Register.
    • tschoeatsch wrote:

      Und was ist dann mit clear timer=1?
      Bei PWM (Phase Correct) zählt der Timer bis zum Top-Wert und dann rückwärts bis 0. Es sind also 510 Schitte (siehe Guenther).
      Ändere ich jetzt den Mode in Fast-PWM (Clear Timer=1), dann zählt der Timer nur von 0 bis 255, dann wieder 0 bis 255 usw.
      Er zählt nur aufwärts. Man hat damit also doppelte PWM-Frequenz bezogen auf Phase Correct PWM.

      Dieses WGM-Bit, welches von "Clear Timer = x" manipuliert wird, ist zufällig (oder vielleicht gewollt) genau das Bit, was zwischen den beiden Modes hin und her schaltet. Das hat bei mir bisher auch immer geklappt, egal welchen Controller ich genommen habe.

      Nochmal kurz:
      Phase Correct Pwm: 510 zählschritte (dual slop), langsamere PWM-Frequenz (Clear Timer=0)
      Fast PWM: 256 Zählschritte (single slop), schnellere PWM-Frequenz (Clear Timer=1)

      Jetzt verstanden?
      Kaum macht man es richtig - und schon geht's!
    • Ok, ich war jetzt mit dem top auf dem falschen Wert. Ich meine aber ein grundsätzliches Problem, egal was jetzt top ist. Im DB vom mega328 steht
      The fast PWM differs from the other PWM option by its single-slope operation. The counter counts from BOTTOM to TOP then restarts from BOTTOM. TOP is defined as 0xFF when WGM2:0 = 3, and OCR0A when WGM2:0 = 7. In non-inverting Compare Output mode, the Output Compare (OC0x) is cleared on the compare match between TCNT0 and OCR0x, and set at BOTTOM. In inverting Compare Output mode, the output is set on compare match and cleared at BOTTOM.

      Also bei bottom wird der Ausgang getoggelt, bei match, je nach Vorgabe, gesetzt oder rückgesetzt. Was ist jetzt, wenn das match jetzt bei bottom ist, bzw bei top? Gilt da überhaupt ein match, oder passiert da nix? Wenn doch was passiert, dann gibt es doch Nadelimpulse am Ausgang, weil bei match was passiert und dann gleich bei bottom wieder was passiert, und wenn match eben gleich top ist, wird gleich danach zu bottom weitergeschaltet.

      Also, kurz gefragt: gibt es ein match bei 0? Gibt es ein match bei top?
      Raum für Notizen

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

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