|
PWM
PWM steht für Pulsweitenmodulation
(engl.: pulse width modulation).
Eigentlich ist das bessere deutsche
Wort für unsere Anwendung: Pulsbreitensteuerung.
Hier wird erklärt, was es
ist und was man damit alles machen kann.
Es gibt zwei verschiedene Wege, PWM mit einem Atmega8 zu
machen:
- Software-PWM:
Man schaltet einfach einen digitalen Ausgang, z. B. PB1,
wiederholend ein und aus und legt jeweils die High- und die Low-Zeit
mit Hilfe von _delay_ms() oder
_delay_us() fest.
(Bei _delay_us() steht das us für Mikrosekunden.)
Diese Variante hat den Nachteil, daß der Atmega8 dann nicht
viel anderes mehr machen kann, als sich ununterbrochen um genau diese
Aufgabe zu
kümmern.
- Hardware-PWM:
Man benutzt die als Hardware vorhandenen drei PWM-Ausgänge des
Atmega8.
Sie heißen: OC1A, OC1B und OC2.
Diese arbeiten unabhängig davon, womit der Atmega8 sonst gerade
beschäftigt ist.
Man sagt einfach einem (oder 2 oder 3) dieser Ausgänge: "Gib eine PWM
von dieser oder jener Form aus!" und der macht das dann unabhängig von
anderen Prozessen.
Hier eine Schaltung für unser Experimentierboard 1 (oder auch
für Steckbrett), die beide PWM-Varianten ermöglicht:
1.
Software-PWM
realisiert 4 Helligkeitsstufen einer LED
Unsere an Pin 15 des Atmega8 (=Ausgang PB1) angelegte
LED leuchtet für 2s nicht, dann schwach, dann halbhell und dann hell.
Hier der Code:
#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>
int main(void)
{
int i;
DDRB |= _BV(PB1);
while(1){
//LED aus
PORTB |=_BV(PB1);
for(i=0;i<100;i++) {
_delay_ms(20);
}
//LED leuchtet schwach
for(i=0;i<100;i++){
PORTB &=
~_BV(PB1); _delay_ms(1);
PORTB
|=_BV(PB1); _delay_ms(19);
}
//LED leuchtet etwa halbhell
for(i=0;i<100;i++){
PORTB &=
~_BV(PB1); _delay_ms(5);
PORTB
|=_BV(PB1); _delay_ms(15);
}
//LED leuchtet hell
for(i=0;i<100;i++){
PORTB &=
~_BV(PB1); _delay_ms(19);
PORTB
|=_BV(PB1); _delay_ms(1);
}
}
return 0;
}
Hier der Code-Ordner.
2. Hardware-PWM realisiert einen
LED-Fader
Unsere an Pin 15 des Atmega8 (=Ausgang OC1A)
angelegte
LED
schalten wir so
schnell ein und aus, das wir das eigentliche Schalten nicht
bemerken. Unser Programm verschiebt dabei des Verhältnis zwischen ein
und aus und läßt somit die LED für uns langsam aufleuchtend und
dann langsam dunkel werdend erscheinen. Diesen Lichteffekt nennen
manche
Leute "faden" und eine solche
Schaltung "Fader".
Hier der Code:
#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>
int main(void)
{
DDRB |= _BV(PB1);
TCCR1A = (1<<WGM11) | (1<<WGM10) |
(1<<COM1A1); // 10bit-Counter, nicht invert. PWM
TCCR1B = (1<<CS10); // Pre-Scaler = 1, also
ohne Teiler
int a = 1023; // höchster Wert = dunkel, wenn LED in
den PORT hineinzeigt, wie bei unserem Board
while(1){
while(a>700){
OCR1A = a;
_delay_ms(10);
a--;
}
while(a<1023){
OCR1A = a;
_delay_ms(10);
a++;
}
}
return 0;
}
Hier der Code-Ordner.
Anmerkungen
und
Aufgaben:
- Du kannst (eventuell mit einem zusätzlichen Transistor) auch
gewaltige superhelle LEDs
oder Lampen
sowie Gleichstrommotoren und Servomotoren ansteuern.
Mit Software-PWM steuern wir in der Mikrocontrollerspielwiese
beispielsweise hier
einen Servomotor an.
- Ich geb's zu: Die Harware-PWM-Befehle sind ziemlich
unübersichtlich.
Wenn Du genau das Benutzen der PWM-Funktionen von Atmega8 erkunden
willst, kannst Du das auch alles im Datenblatt
nachlesen.
- PWM-Experimente gibt es auf der Mikrocontrollerspielwiese für den
Attiny13 hier.
|