Technische Informatik; Hardwarenahe Programmierung

PWM Erweitert

Inhalt

PWM und die Timer

Die PwmOut Hardware ist an bestimmte Timer gebunden, sodass eine Änderung der Periodendauer auf einem Output sich auch die anderen mit ändern. Die Pulsweite kann unabhängig für jeden Output-Pin geändert werden. Weiters ist die Reihenfolge der Befehle wichtig, damit der Duty-Cycle richtig zugeordnet wird (bei zwei Objekten pwmOne und pwmTwo würde das zweite einen invertierten bekommen):

pwmOne.period_us(100); // zuerst die Periode für beide dann die Dauer
pwmTwo.period_us(100);
 
pwmOne.write(0.20f); 
pwmTwo.write(0.20f);

Achtung

Die Implementationsdetails der PWM Pins des LPC1768 haben nur einen Timer für alle Pwm-Pins, ändert man die Periode für einen Pin, ändert sich diese auch für die anderen.

Der Nucleo L432KC besitzt drei Timer, die wie im folgenden Beispiel zu programmieren sind:

PWMam

#include "mbed.h"

PwmOut led1(D0);    // Timer 1
PwmOut led3(D3);    // Timer 1
PwmOut led15(A1);   // Timer 15 auch A2 - ext. Led
PwmOut led16(A5);   // Timer 16 auch D5-SCL - ext. Led


int main() {
    // specify period first, then everything else
    led1.period(4.0f);      // 4 second period Timer 1
    led16.period(2.0f);     // 2 second period Timer 16
    led15.period(1.0f);     // 1 second period Timer 15
    led1.pulsewidth(2);     // 2 second pulse (on)
    led3.pulsewidth(3);     // 3 second pulse (on)
    led16.pulsewidth(1);    // 1 second pulse (on)
    led15.pulsewidth(0.5);  // 0.5 second pulse (on)
    while(1){};  
}

RC Servo's


RC Servo's bzw. Modellbauservos werden über eine Pulsweitenmodulation (PWM), also über den duty cycle oder die Pulsweite (pulse width) des PWM Signals, angesteuert. Über die Breite der Pulse wird der Winkel, auf den der Servoarm gestellt werden soll, gesteuert. Gängig ist ein 50-Hz-Signal (20 ms Periodenlänge), welches zwischen 500 Mikrosekunden (linker Anschlag, 0 Grad) und 2500 Mikrosekunden (rechter Anschlag, 180 Grad) auf High-Pegel und den Rest der Periodenlänge auf Low-Pegel ist. Viele Servos haben in diesem Wertebereich jedoch nicht ihre volle Bewegungsfreiheit ausgenutzt bzw. können sich zwischen anderen Gradzahlen bewegen. Siehe auch Servosteuersignal und RC-Servos

/media/uploads/fpucher/servo1.jpg /media/uploads/fpucher/servo2.jpg

/media/uploads/fpucher/servosignaling.jpg

This example code uses a period of 0.020s and increases the pulse width by 0.0001s on each pass. This will cause an increase of .5% of the servo's range every .25s. In effect the servo will move 2% of its range per second, meaning after 50 seconds the servo will have gone from 0% to 100% of its range.

#include "mbed.h"
 
PwmOut servo(p21);
 
int main() {
    servo.period(0.020);          // servo requires a 20ms period
    while (1) {
        for(float offset=0.0; offset<0.001; offset+=0.0001) {
            servo.pulsewidth(0.001 + offset); 
	// servo position determined by a pulsewidth between 1-2ms
            wait(0.25);
        }
    }
}

Untersuchen Sie folgende Mbed-Bibliothek.

Servo myservo(P0_8);

myservo.calibrate(range, 45.0); 
myservo = position;
wait_ms(500);

/media/uploads/fpucher/servomotorpwmtiming.jpg

SoftPwm

Die PWM-Ausgabe per Software kann an jeden Pin ausgegeben werden; kann also den PwmOut ersetzen.

Aufgaben

  1. An den Rot-Anteil der RGB-LED (R-LED) sollen 10.000 Pulse gesendet werden, wobei die R-LED eine geringe Helligkeit haben soll, nach weiteren 10.000 Pulsen etwas heller werden usw. bis sie ganz Hell ist. https://developer.mbed.org/forum/helloworld/topic/3329/
  2. Wie kann man PwmOut ein bzw. ausschalten. Probieren Sie den duty cycle auf 0 bzw. 1 zu setzen?

All wikipages