wer's haben will hier der Quellcode zur Ansteuerung einer RGB-LED.
Wer schimpfen will, solls tun, und es besser machen!
Dies ist für die Einsteiger gedacht, die Input zum uC-Lernen suchen

Code: Select all
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdlib.h>
/****************************
RGB-LED-Steuerung
26.02.06 Th. de Buhr
Ansteuerung einer RGB-LED
Port B: 0=R, 1=G, 2=B
****************************/
#define CLK 8000000
#define delay_ms(ms) _delay_loop_2(ms * (CLK/4000))
#define delay_us(us) _delay_loop_2(us * (CLK/4000000))
#define bit_on(BYTE, BIT) BYTE |= 1 << BIT;
#define bit_off(BYTE, BIT) BYTE &= ~(1 << BIT);
volatile char colour=1, led_out=0;
volatile int time=0, pwm=0;
volatile char palette[12]={0,1,2,4,1,2,3,4,5,6,7};
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 0x80;
time++;
if(time>=100) time=0;
if(time>pwm)
{
led_out=0;
}
else
{
led_out=palette[colour];
}
PORTB = led_out;
}
int main()
{
char i=0;
//pwm = 0...100%, colour = 0...10
DDRB=0xFF;
PORTB=0x00;
DDRD=0xFF;
PORTD=0x00;
//Timer 8Bit setup
bit_off(TCCR0, CS00); //Int. CLK/8
bit_on(TCCR0, CS01);
bit_off(TCCR0, CS02);
TCNT0 = 0x00; //Timer-Reg. löschen
bit_on(TIMSK, TOIE0); //Overflow-Int. enable
sei();
delay_ms(20); //Pause, falls Programmierfehler den Programmierport überschreibt
while(1)
{
for(i=0; i<=100; i++)
{
pwm=i;
delay_ms(20);
}
if((++colour) > 10) colour=1;
}
}
edit:
-----
Das ganze läuft auf einem Atmel AVR (AT Mega

PWM ist bei Mikrocontrollern die gängige Variante, wenn es darum geht, Lampen (oder Motoren

Man legt nicht einen analogen Pegel auf die LED (Scheinwerfer, Gleichstrommotor), sondern schaltet den maximalpegel ständig an/aus.
Durch den Tastgrad (=An-Zeit / Aus-Zeit oder andersherum

Das Programm verwendet zum Erzeugen des PWM (=Pulsweitenmodulation) einen 8Bit-Timer. In der ISR (Interrupt - Service-Routine) Wird der PWM generiert. Mit 2 Variablen lassen sich Farbe und Tastgrad (in %) bestimmen, die gesamte Impulslänge wird durch den Timer festgelegt.
Je höher die Periodendauer des PWM-Signals, desto "ruckelfreier" läuft das Dimmen bzw.der Motor.
Aber auch hier sind Grenzen gesetzt (z.B. die Induktivität eines Motors, die mag ja bekanntlich schnelle Spannungsänderungen gar nicht gerne und geht die Änderung ganz gemächlich an (anderes Thema!).
btw: Wens interessiert: "Architektur" des Programms ist Round Robin mit Interrupt. Wohl für solche Anwendungen das Gängigste...
edit: Bug korrigiert, s. unten.
Greetz
medra