-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: PWM mit ATmega644

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791

    PWM mit ATmega644

    Anzeige

    Hallo ATmega Spezialisten,

    ich stehe auf dem Schlauch.

    Ich möchte eine PWM von 10 kHz mit den Timern 0 und 1 des ATmega644 erzeugen.

    Gewünschte Bedingungen:
    F_CPU = 20 MHz
    Timer 0: PWM Mode 3 (Fast PWM, TOP 0xFF, Prescaler 8 )
    Timer 1: PWM Mode 14 (Fast PWM, TOP ICR1, Prescaler 8 )

    Timer 0:
    Code:
        TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(1<<WGM00);
          TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00);
    Timer 1:
    Code:
        TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(0<<WGM10);
         TCCR1B = (0<<ICNC1)|(0<<ICES1)|(1<<WGM13)||(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);
        TCCR1C = 0;
        ICR1 = 249;            // 10kHz
    Was ist mein Problem?
    Timer 0 produziert eine wunderbare PWM mit 10 kHz (genau 9766 Hz).
    Timer 1 zeigt mit Oszi aber eine PWM von 20 kHz.

    Kann mir jemand sagen, was ich übersehe?
    Geändert von Dirk (02.09.2015 um 09:09 Uhr)
    Gruß
    Dirk

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    .. ich stehe auf dem Schlauch .. F_CPU = 20 MHz .. Timer 1: PWM Mode 14 (Fast PWM, TOP ICR1, Prescaler 8 ) ..
    Hmmm, zuerst mal nur so: die Nullen werden üblicherweise nicht geschrieben; zum Start sind die Register genullt und meist schaltet man zur Laufzeit nicht dauernd um . . . WENN Du etwas explizit löschen möchtest dann ist dies üblich:
    Code:
      TCCR1A &= ~(1<<COM1A1)|(1<<COM1B1);   // Clear/set OC1A/OC1B on Cmp Match   S132
    So. Deine Timer1-initialisierung, modifiziert (und jedenfalls für MICH übersichtlicher und informativer - NUR Befehle machen selbst Profis nicht oft)
    Code:
         TCCR1A |=  (1<<COM1A1)|(1<<COM1B1);  // Clear/set OC1A/OC1B on Cmp Match
         TCCR1A |=  (1<<WGM11);               // Mode Fast PWM, TOP ICRn, 1. Teil
         TCCR1B |=  (1<<WGM13)|(1<<WGM12);    // Mode Fast PWM, TOP ICRn, 2. Teil
         TCCR1B |=  (1<<CS11);                // clkI/O/8 (From prescaler)
                                              //   => 20e6/8 = 2 500 000
         TCCR1C  =     0;                     // Wo in Deinem Code wird denn
                                              //   IRGENDEIN Bit auf 1 gesetzt ??
                                              // Würde ich nicht coden
         ICR1    = 249;               // 10kHz (F_CPU / (Prescaler * (ICR1 + 1)))
                                      // Die 10k sind ein netter Wunsch aber ..
                                      // .. das Timing Diagramm auf S 121 des
                                      //    ATmega164A-PA_bis_1284-P_8272G_01-15
                                      //    erklärt, dass es doch 20 kHz sind.
                                      //    Daher der Name "FAST"-PWM
    Anmerkung: Fehler vorbehalten, ich habs ja nicht getestet )

    Bei mir wird z.B. so initialisiert
    Code:
    // =====        s. Dokument ATmega164A-PA_bis_1284-P_8272G_01-15
    // ============================================================================= =
    // ==  PWM-Routinen zur Motoransteuerung
     void TC1PWM_init(void)         //Init Timer/Counter1 f Erzeugung des PWM-Signals
     {                              //
      TCCR1A &= ~(1<<COM1A1)|(1<<COM1B1);   // Clear/set OC1A/OC1B on Cmp Match   S132
                    // DISABLED OC1A/OC1B bzw Port PB1/B2, ERST mit Motorstart enablen
      TCCR1A |=  (1<<WGM10);                // Dazu noch 
      TCCR1B |=  (1<<WGM12);                // Fast PWM, 8 Bit TOP=0xFF=dez255     133
      TCCR1B |=  (1<<CS11);         // Prescaler ist clk/8 =>  9,8 kHz             135
            // theoretisch: 20 MHz / 8 / 255  =>  9,803922 kHz, DMM-Messung 9,78 kHz
      TIMSK1 &= ~(1<<OCIE1A)|(1<<OCIE1B);   // T/C1 Oput CmpA+B Match intrrpt dsabld
      TIMSK1 &= ~(1<<TOIE1);                // T/C1 Ovrflw intrrpt dsabled       ~S137
      OCPWM1    = 0;                        // PWM auf Null setzen
      OCPWM4    = 0;                        // PWM auf Null setzen
      isum12    =  isum34    = 0;
      ie_mot12  =  ie_mot34  = 0;
      ie_alt12  =  ie_alt34  = 0;
     }              // Ende void TC1PWM_init(void)
    // ============================================================================= =
    PS: Kleine Erkläuterung zum Nullen eines Bits
    Code:
      TCCR1A &= ~(1<<COM1A1);
      TCCR1A      ...    Ziel
      &           ...    UND-Operator
      &=          ...    das UND als Zuweisungsoperator,
                         => weist das Ziel als Parameter zu
      ~           ...    der unäre Operator bildet das
                         Bit-Komplement => "1" (in 1<<COM1A1)
                         wird zur "0"
    Geändert von oberallgeier (02.09.2015 um 10:32 Uhr) Grund: PS: Kleine Erläuterung
    Ciao sagt der JoeamBerg

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hi oberallgeier,

    danke für deine schnelle Antwort!
    Die 10k sind ein netter Wunsch aber ..
    .. das Timing Diagramm auf S 121 des
    ATmega164A-PA_bis_1284-P_8272G_01-15
    erklärt, dass es doch 20 kHz sind.
    Daher der Name "FAST"-PWM
    Ja, aber genau von der Seite 121 stammt ja meine Formel zur Berechnung von TOP (ICR1 = 249):
    f_PWM = f_I/O / (N * (1 + TOP))
    ... also:
    f_PWM = 20000000 / (8 * (1 + 249))
    = 20000000 / 2000
    = 10000 Hz = 10 kHz

    Denkst du, das stimmt so nicht?
    Gruß
    Dirk

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    .. Ja, aber genau von der Seite 121 stammt ja meine Formel zur Berechnung von TOP (ICR1 = 249) .. Denkst du, das stimmt so nicht?
    Hmmmmm, also bei Dokumentationen mit mehr als 500 Seiten denke ich nicht mehr soooo oft, da hilft mir z.B. manchmal der Frequenzanalysator weiter . . .

    Auf Seite 121 der von mir genannten Dokumentation steht keine einzige Formel. Die von Dir zitierte Formel steht in der zitierten Dokumentation auf Seite 122 - und sorry für diese Pingeligkeit. Warum hast Du Dich entschieden, das Clear/Set-Bit zu aktivieren? Was bewirkt das ? Da steht doch im Abschnitt 16.10.3 Fast PWM mode weit unten (S 122) noch ne Anmerkung dazu !? Wie geschrieben - für mich sind die Erklärungen nicht immer soooo verständlich mit all den Flags auf wenn und aber . . .
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Zitat Zitat von Dirk Beitrag anzeigen
    ... Kann mir jemand sagen, was ich übersehe?
    Die Konfiguration scheint mir richtig zu sein. Die OCR Register der beiden Timer werden aber zu unterschiedlichen Zeiten aktualisiert. Timer0 im Mode 3 update OCRn at TOP, Timer1 im Mode 14 update OCRx at BOTTOM.

    Problem könnte deshalb vielleicht im übrigen Programm liegen?

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    @oberallgeier:
    Clear/Set-Bit?
    Meinst du COM1A1/COM1A0? Die habe ich auf nicht-invertierende PWM (1:0) eingestellt.

    @searcher:
    Die OCR Register der beiden Timer werden aber zu unterschiedlichen Zeiten aktualisiert. Timer0 im Mode 3 update OCRn at TOP, Timer1 im Mode 14 update OCRx at BOTTOM.
    Das muss ich mir ansehen. Vielleicht mit Mode 1 (8-Bit Fast PWM)? Aber: Kann dadurch die PWM Frequenz anders sein als in der Berechnung, die ja für alle Fast-PWM Modi gelten müßte?
    Problem könnte deshalb vielleicht im übrigen Programm liegen?
    Das besteht zum Test nur aus einer Schleife, in der der PWM-Wert rauf und runter gezählt wird. Die PWM funktioniert auch bei beiden Timern gut, d.h. die angeschlossenen Motoren werden normal angesteuert.
    Gruß
    Dirk

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Zitat Zitat von Dirk Beitrag anzeigen
    @searcher:
    Das muss ich mir ansehen. Vielleicht mit Mode 1 (8-Bit Fast PWM)? Aber: Kann dadurch die PWM Frequenz anders sein als in der Berechnung, die ja für alle Fast-PWM Modi gelten müßte?
    Mode 1 für Timer1 könntest Du ja mal ausprobieren. PWM Frequenz sollte sich normalerweise nicht durch den Updatezeitpunkt der OCRn ändern. Wenn die COM Bits aber bei beiden Timern gleich zB auf nicht invertierendem PWM stehen, könnte der Beschreibzeitpunkt der OCRn durch das Programm unterschiedliche Auswirkungen haben. Ich habe das nicht komplett durchdacht und versuche jetzt aber nicht weiterzudenken ...

    Mir fiel nur nix Besseres ein - außer Meßfehler oder HW-Fehler (zB Kurzschluß zu irgendetwas, daß noch einen Zyklus hinzufügt) Wie gesagt, Konfiguration scheint mir richtig zu sein.

    Das besteht zum Test nur aus einer Schleife, in der der PWM-Wert rauf und runter gezählt wird. Die PWM funktioniert auch bei beiden Timern gut, d.h. die angeschlossenen Motoren werden normal angesteuert.
    Programm auf das unbedingt notwendigste reduzieren und wenn Fehler noch drin, das Minimalprogramm mal posten.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    @Searcher:
    Ich habe jetzt mal die 8-Bit Fast-PWM (Mode 5: WGM13:10 = 0101) getestet:
    Timer 1:
    Code:
    TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(0<<WGM11)|(1<<WGM10);
    TCCR1B = (0<<ICNC1)|(0<<ICES1)|(0<<WGM13)||(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);
    Das geht auch, ist aber auch lt. Oszi eine 20 kHz PWM.

    Merkwürdig ...

    Hat jemand von euch ein Oszi oder Frequenzmesser und kann evtl. mal den Mode 14 nachmessen?
    Gruß
    Dirk

  9. #9
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    .. Hat jemand von euch ein Oszi oder Frequenzmesser und kann evtl. mal den Mode 14 nachmessen?
    Kann ich machen, mach ich gern, denn es interessiert mich ja selbst. Aber ich hab grad stundenlages Herumspielen mit dem Oskar an einer SDA bei I²C-Taktraten zwischen 40 k und 500 k hinter mir, hab diese Bildschirmrätsel eben abgeschaltet und weggeräumt. Sprich: für heut is der Riemen runter. ABer vielleicht hat jemand anders Lust - TV is eh mies, Wetter s..feucht . . .

    Trotz allem: schönen Abend.

    Übrigens - der Code sieht weiterhin - ähhhh - xxxzensiert (*ggg*) aus.
    Ciao sagt der JoeamBerg

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    So, ich gebe auf. Ich habe mehrere Modi, Prescaler und TOP Werte probiert:
    Ergebnis: Frequenz bleibt konstant, egal welche Werte ich einsetze. PWM ist aber von 0 bis 100% Duty nutzbar.
    Lediglich die Änderungen an COM1A1/COM1A0 und COM1B1/COM1B0 zeigen Wirkung: Tatsächlich wird das PWM Signal invertiert.

    Jetzt kommt der Hammer:
    Dies hier:
    Code:
    TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(0<<WGM10);
    TCCR1B = (0<<ICNC1)|(0<<ICES1)|(1<<WGM13)||(1<<WGM12)|(0<<CS12)|(0<<CS11)|(0<<CS10);
    Was denkt ihr, was passieren müßte (Auflösung: Timer gestoppt)?
    Bei mir: PWM 20 kHz.
    Ich gebe auf.

    P.S.: Kann man vor Auslieferung eines ATmega z.B. Bits in TCCRxA/B so festlegen, dass sie via Programm im Flash nicht mehr zu ändern sind?
    Oder kann man so etwas in einem Bootloader machen?
    Grund der Frage: Ich habe das ATmega644 Board nicht neu, sondern gebraucht übernommen.
    Mich irritiert nämlich, dass alle Änderungen (bis auf COM1A1/COM1A0 und COM1B1/COM1B0) keinen erkennbaren Effekt auf die Timerfunktion haben.
    Gruß
    Dirk

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Signalabtastung mit ATMEGA644
    Von blackflame2025 im Forum AVR Hardwarethemen
    Antworten: 7
    Letzter Beitrag: 01.11.2011, 08:43
  2. Atmega644 RC5
    Von dehnelement im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 13
    Letzter Beitrag: 20.03.2010, 11:52
  3. FuseBits am Atmega644
    Von AVR_anfänger im Forum Robby CCRP5
    Antworten: 1
    Letzter Beitrag: 02.09.2008, 12:49
  4. atmega644 und bascom -- ADC_REFMODEL
    Von kolisson im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 27
    Letzter Beitrag: 14.03.2008, 00:27
  5. ATMEGA644 Programmieren
    Von Elektronik303 im Forum AVR Hardwarethemen
    Antworten: 49
    Letzter Beitrag: 30.03.2007, 19:36

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •