www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fragen zu extrem langsamer PWM und Prescaler, PREA, DIVA


Autor: Buddler B. (buddler) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mittels PWM ein Ventil regelmäßig zu schalten. Die 
Periodenlängen dabei sind bis zu 300 sek und einstellbar von 10 bis 
300sek.
Mein AVR32 UC3A1512 läuft auf 12 MHz und der Vorteiler für den PWM-Kanal 
(CPRE aus dem CMR-Register des Kanals) steht auf 1024 (0xA).
Damit komme ich dann bei 16 bit max auf eine Periode von 5.59 sek. 
Deshalb dachte ich, dass ich noch eine 2. Vorteiler nutzen kann und habe 
das so angestellt:
void PWM2(int channel, int duty, int period)
{
  AVR32_GPIO.port[1].gperc = 1 << (19+channel);              // PB20 = PWM Channel[1]
  AVR32_GPIO.port[1].pmr0c = 1 << (19+channel);              // PB20 = Function A
  AVR32_GPIO.port[1].pmr1c = 1 << (19+channel);              // PB20 = Function A


  AVR32_PWM.mr =     0 << AVR32_PWM_PREB_OFFSET |        // PWM PREB Divider Input clock
            0xa << AVR32_PWM_PREA_OFFSET |        // PWM PREA Divider Input clock
            0 << AVR32_PWM_DIVB_OFFSET |        // PWM CLKB Divider factor
            0xff << AVR32_PWM_DIVA_OFFSET ;        // PWM CLKA Divider factor


  AVR32_PWM.channel[channel].cmr =
                0 << AVR32_PWM_CPD_OFFSET |    // Writing to the CUPD1 will modify the duty cycle at the next period start event.
                0 << AVR32_PWM_CPOL_OFFSET |  // The output waveform starts at a Low level.
                0 << AVR32_PWM_CALG_OFFSET |   // The period is left aligned.
                0x3 << AVR32_PWM_CPRE_OFFSET ;  // PWM CLKA Divider factor

  AVR32_PWM.channel[channel].cprd = period;          // max pwm Value
  AVR32_PWM.channel[channel].cdty = duty;            // duty

  AVR32_PWM.ena |= 1 << channel;                // Enable PWM Channel[1]
}

Leider stellt sich nicht der gewünschte Effekt ein (MCK/(PREA*DIVA)).

Wer weiß rat oder hat selbiges schon probiert?

Autor: Hans Mayer (hansilein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum willst Du für etwas so langsames Hardware-PWM nutzen?

Autor: Buddler B. (buddler) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ich zur Zeit PWM besser verstehe als Timer, d.h. ich schaffe es 
noch nicht mit Timer/counter und Interrupts zu arbeiten. Wie wäre da die 
herangehensweise (und letztendlich funktioniert das doch ähnlich, 
oder?)?

Autor: Buddler B. (buddler) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, wie ich nochmal nachgelesen habe, ist der interne Counter 20bit 
groß, d.h. ich kann bis 1048575 zählen, was mir bei maximalen Vorteiler 
und 12 MHz 89.4784 s Periodenlänge (sogar selbst gemessen) ermöglicht. 
Schon etwas näher dran, aber immer noch daneben. Wie löst man das 
Problem vielleicht eleganter?

Als Notlösung könnte ich den Chiptakt auf z.B. 3 MHz reduzieren, was 
aber Nachteile bringt.

Autor: Hans Mayer (hansilein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sich jede sekunde einen interrupt geben lassen, zähler inkrementieren, 
wenn er eine bestimmte zahl, z.b. 300 überschritten hat ausgang 
schalten?

Autor: Buddler B. (buddler) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe noch eine Frage:

Standardmäßig wird beim AVR32 bei Änderungen der Periodenlänge oder der 
Pulsbreite erst im nächsten Periodendurchlauf der Parameter geändert.
Da ich aber sofort eine Änderung möchte, dachte ich, es wäre möglich die 
PWM des Kanals zu dekativieren und einfach neu zu initialisieren.
Allerdings setzt sich der µC dort mit dem A**** drauf und macht selbst 
bei folgender Variante Änderungen erst im nächsten Periodendurchlauf:
if (buttons[1] == 1){
      up++;
      if(up > 80){up = 80;}
      AVR32_PWM.dis = (1 << 2);             //PWM for channel 2 disabled
      PWM2(2, 2343, 11718+up*11718); //11718 entspricht einer Sekunde
    }

Code der Funktion PWM2:
void PWM2(int channel, int duty, int period)
{
  AVR32_GPIO.port[1].gperc = 1 << (19+channel);              // PB20 = PWM Channel[1]
  AVR32_GPIO.port[1].pmr0c = 1 << (19+channel);              // PB20 = Function A
  AVR32_GPIO.port[1].pmr1c = 1 << (19+channel);              // PB20 = Function A
  AVR32_PWM.channel[channel].cmr =
                0 << AVR32_PWM_CPD_OFFSET |    // Writing to the CUPD1 will modify the duty cycle at the next period start event.
                1 << AVR32_PWM_CPOL_OFFSET |  // The output waveform starts at a Low level.
                0 << AVR32_PWM_CALG_OFFSET |   // The period is left aligned.
                0xa << AVR32_PWM_CPRE_OFFSET ;  // PWM CLKA Divider factor

  AVR32_PWM.channel[channel].cprd = period;          // max pwm Value
  AVR32_PWM.channel[channel].cdty = duty;            // duty
  AVR32_PWM.ena |= 1 << channel;                // Enable PWM Channel[1]
}

Wie gesagt, über CUPD lässt sich auch erst in der nächsten Periode etwas 
ändern.

Wie kann man PWM sofort stoppen und wieder neu starten lassen?

Das Manual sagt:
"CNT: Channel Counter Register
Internal counter value. This register is reset when:
• the channel is enabled (writing CHIDx in the ENA register).
• the counter reaches CPRD value defined in the CPRDx register if the 
waveform is left aligned."

Das entsprechende Bit wird ja auch gesetzt ... :-/

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.