-         

Ergebnis 1 bis 7 von 7

Thema: Software PWM

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    20.08.2006
    Beiträge
    339

    Software PWM

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo,

    mal eine Frage zum Software PWM:
    Braucht man da pro PWM einen Timer?
    Oder kann ein Timer mehrere PWM Signale erzeugen?
    Auflösung sollte 10bit sein, wenn aber nur 8bit gehen ist es auch egal...


    Viele Grüße,
    Johannes

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Wenn man keinen Bock schiesst sollte ein Timer reichen, so kompliziert ist es ja nicht.


    Beachte, daß
    PWM-Frequemz = Timer-Frequenz / Auflösung

    Mit einer Soft-PWM sind also nicht so hohe Frequenzen erreichbar etc.
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    20.08.2006
    Beiträge
    339
    Hallo,
    welche Timerfrequenz würdest du für LEDs empfehlen?

    Viele Grüße,
    Johannes

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Für eine LED mit 11 Helligkeitsstufen (0%, 10%...100%) reicht meiner Erfahrung nach eine PWM-Auflösung von 100, wobei man die duty-cycles quadratisch verteilt, also 0/100, 1/100, 4/100, ...

    Da LEDs praktisch unträge sind und es nicht flimmern sollte (auch nicht, wenn die Anzeige im Blickfeld wandert), solltes es schon allermindestens eine 100Hz-PWM sein.

    Wenn wir von einer Timer-IRQ-Rate von 20kHz ausgehen hast du noch Luft. Die Auflösung könntest du zB auf 200 erhöhen (ca. 15 Helligkeiten) oder alternativ die PWM-Frequenz auf 200Hz steigern.

    Das Flimmern kann man auch einfach dadurch reduzieren, daß man nicht mit einer PWM ansteuert.

    Beispiel: Nehmen wir mal an, wir hätten eine PWM mit einer Auflösung von 5 und wollen 2/5 duty. Eine PWM würde dann liefern
    11000110001100011000...
    Die selbe Helligkeit und kann man aber auch erreichen mit
    10100101001010010100...
    Das hat viel kürzere Intervalle gleichen Pegels, was das Flimmern reduziert.

    Vom algorithmischen Aufwand ist das genauso einfach wie ne Soft-PWM, formal aber eine Überlagerung von phasenverschobenen PWMs, hier von 2 Stück.
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    20.08.2006
    Beiträge
    339
    Hallo,

    danke für die Erklärung..
    Du hast nicht zufällig einen kleinen Beispielcode in C (oder ASM), oder?
    Weil ich weiß nicht wie ich mit einem Timer mehrere PWMs erzeugen soll...

    Viele Grüße,
    Johannes

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Generell kann man sagen, das je höher die Auflösung und Wiederholrate der PWM sein soll, desto mehr Gedanken muss man sich im Vorfeld machen und desto optimaler muss der Code aussehen.

    Reicht für es 1 oder 2 Kanäle noch aus jeden einzelnen Kanal einzeln zu vergleichen und separat auszugeben, so muss man bei 8 Kanälen in 8 Bit Auflösung für eine annehmbare Wiederholrate (ab 250 Hz) schon etwas tiefer in die Codekiste greifen.
    Hannes Lux schlug auf www.mikrocontroller.net z.B. das folgende Code Konstrukt vor:

    Code:
     cp pwz,soll0          ;Sollwert0 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll1          ;Sollwert1 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll2          ;Sollwert2 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll3          ;Sollwert3 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll4          ;Sollwert4 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll5          ;Sollwert5 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll6          ;Sollwert6 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     cp pwz,soll7          ;Sollwert7 erreicht?
     ror wl                ;Ergebnis (Carry) sichern
     com wl                ;invertieren wegen L-aktiven Ausgängen
     out aus,wl            ;Ergebnisse ausgeben
    Wie meine Vorredner schon erwähnten läuft dieser Code in einer Timer Interupt Routine.

    Vielleicht reicht das ja als Denkanstoß aus.


    Für eine 10 Bit Software PWM dürfte ein wesentlich höherer Aufwand von Nöten sein.
    Aber dazu mehr, wenn ich meine Theorien in dieser Richtung in die Praxis umgesetzt habe.

    Grüße,
    Hanni
    Grundregeln des Forenpostings:
    1. Nutze niemals die Suchfunktion!
    2. Überprüfe niemals die Topics nach Ähnlichkeiten!
    3. Schreibe alles in hellgelb!

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Mein Beispielcode aus dem Wiki (Artikel PWM) umgesetzt nach C, hier für 8 Kanäle, sie sämtilch an einem 8-Bit-Port ausgegeben werden, uns zwar pwm[0] an Pin0, etc

    Code:
    typedef struct
    {
        uint8_t tick;
        uint8_t duty;
    } pwm_t;
    
    pwm_t pwm[8];
    
    void job_pwm (uint8_t max)
    {
        uint8_t i;
        //uint8_t max = 100;
        uint8_t port = 0;
        
        uint8_t * ppwm = (uint8_t*) & pwm[0];
        
        for (i= sizeof (pwm) / sizeof (pwm[0]); i > 0; i--)
        {
            uint8_t tick = * ppwm + 1;
            
            if (tick >= max)
                tick = 0;
                
            * ppwm++ = tick;
            
            port >>= 1;
            
            if (tick < * ppwm++)
                port |= 0x80;
        }
        
        PORTB = port;
    }
    Für Assembler kommt direkt von avr-gcc und kann als Vorlage dienen:
    Code:
    .global	job_pwm
    job_pwm:
    	ldi r20,lo8(0)	 ;  port,
    	ldi r30,lo8(pwm)	 ;  ppwm,
    	ldi r31,hi8(pwm)	 ;  ppwm,
    	ldi r21,lo8(8)	 ;  i,
    .L26:
    	ld r19,Z	 ;  tick,* ppwm
    	subi r19,lo8(-(1))	 ;  tick,
    	cp r19,r24	 ;  tick, max
    	brlo .L24	 ; ,
    	ldi r19,lo8(0)	 ;  tick,
    .L24:
    	st Z+,r19	 ; , tick
    	lsr r20	 ;  port
    	ld r18,Z+	 ;  tmp50,
    	cp r19,r18	 ;  tick, tmp50
    	brsh .L23	 ; ,
    	ori r20,lo8(-128)	 ;  port,
    .L23:
    	subi r21,lo8(-(-1))	 ;  i,
    	brne .L26	 ; ,
    	out 56-0x20,r20	 ; , port
    	ret
    Die Bits werden in "port" aufgesammelt und gemeinsam ausgegeben.
    Disclaimer: none. Sue me.

Berechtigungen

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