RGB LED im Wechsel leuchten lassen mit Software PWM.
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t pwmRed = 10;
uint8_t pwmGreen = 10;
uint8_t pwmBlue = 10;
// Overflow Interrupt Routine von Timer 0
ISR(TIMER0_OVF_vect) {
static uint8_t inc = 0;
static uint8_t state = 0;
inc++;
if(inc == 25) {
inc = 0;
if(state == 0) {
state = 1;
// Red
pwmRed = 100;
pwmGreen = 0;
pwmBlue = 0;
} else if(state == 1) {
state = 2;
// Blue
pwmRed = 0;
pwmGreen = 100;
pwmBlue = 0;
} else if(state == 2) {
state = 3;
// Green
pwmRed = 0;
pwmGreen = 0;
pwmBlue = 100;
}
else if(state == 3) {
state = 4;
pwmRed = 0;
// Cyan
pwmGreen = 100;
pwmBlue = 100;
}
else if(state == 4) {
state = 0;
// Magenta
pwmRed = 100;
pwmGreen = 0;
pwmBlue = 100;
}
}
}
int main() {
// PORTB als Ausgang schalten
DDRB = 0xFF;
// Alle Ausgaenge auf 0 schalten
PORTB = 0x00;
// Prescaler von Timer0 auf 1024 stellen
TCCR0B |= (1 << CS02) | (1 << CS00);
// Timer 0 Overflow Interrupt aktivieren
TIMSK0 |= (1 << TOIE0);
// Interrupts einschalten
sei();
uint8_t inc = 0;
for(;;) {
// Alle Lampen einschalter
if(inc == 0) {
PORTB |= (1 << PB0);
PORTB |= (1 << PB1);
PORTB |= (1 << PB2);
}
// Lampen entsprechend dem PWM Wert ausschalten
if(inc == pwmRed) {
PORTB &= ~(1 << PB0);
}
if(inc == pwmGreen) {
PORTB &= ~(1 << PB1);
}
if(inc == pwmBlue) {
PORTB &= ~(1 << PB2);
}
inc++;
}
}
Für AVR UNO und avrdude als Programmer "arduino" und als MCU "m328p"
Makefile
all:
avr-g++ -O1 -Wall -Wextra -Wconversion blink.cpp -mmcu=atmega328p -o blink.elf
avr-objcopy -O ihex blink.elf blink.hex
load:
avrdude -v -p m328p -c arduino -P /dev/ttyACM0 -U flash:w:blink.hex:i -i 11
clean:
rm -f *.o *.hex *.elf