main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
/*
H: der Farbton als Farbwinkel H auf dem Farbkreis (z. B. 0° = Rot, 120° = Grün, 240° = Blau)
S: die Sättigung S in Prozent (z. B. 0% = keine Farbe, 50% = ungesättigte Farbe, 100% = gesättigte, reine Farbe)
V: der Grauwert V als Prozentwert angegeben (z. B. 0% = keine Helligkeit, 100% = volle Helligkeit)
Skalierung der HSV Werte:
H: 0-255, 0=rot, 42=gelb, 85=grün, 128=türkis, 171=blau, 214=violett
S: 0-255, 0=weißtöne, 255=volle Farben
V: 0-255, 0=aus, 255=maximale Helligkeit
*/
#define Ledport PORTB // RGB Led Port
#define DDR_Ledport DDRB
#define DDR_Inputport DDRC
#define R_PIN 0 // R Ausgang
#define G_PIN 1 // G
#define B_PIN 2 // B
#define INVERT 0 // Ausgang Low aktiv ?
#define Time 1 // Statusbit für Farbwechsel
// Prototypen
void hsv_to_rgb (unsigned char h, unsigned char s, unsigned char v);
// Globale Variabeln (Timer ISR)
volatile unsigned char Red, Green, Blue; // PWM Register
volatile unsigned char Flags;
//-------------------------------------------------------------------------------
//Hauptprogramm
//-------------------------------------------------------------------------------
int main(void)
{ unsigned char H,S,V;
DDR_Ledport=255;
H=0;
S=255;
V=255; // HSV Startwerte: rot, volle Helligkeit
hsv_to_rgb(H,S,V); // HSV to RGB
TCCR0=1;
TIMSK = (1<<TOIE0); // T0 Starten, Overflow Interrupt f/256
sei(); // Enable Interrupts
for(;;)
{
if (Flags&Time)
{ Flags&=~Time;
H++;
hsv_to_rgb(H,S,V);
}
}
}
//-------------------------------------------------------------------------------
//HSV nach RGB konvertieren
//-------------------------------------------------------------------------------
void hsv_to_rgb (unsigned char h, unsigned char s, unsigned char v)
{
unsigned char r,g,b, i, f;
unsigned int p, q, t;
if( s == 0 )
{ r = g = b = v;
}
else
{ i=h/43;
f=h%43;
p = (v * (255 - s))/256;
q = (v * ((10710 - (s * f))/42))/256;
t = (v * ((10710 - (s * (42 - f)))/42))/256;
switch( i )
{ case 0:
r = v; g = t; b = p; break;
case 1:
r = q; g = v; b = p; break;
case 2:
r = p; g = v; b = t; break;
case 3:
r = p; g = q; b = v; break;
case 4:
r = t; g = p; b = v; break;
case 5:
r = v; g = p; b = q; break;
}
}
cli(); // Kein Interrupt beim übernehmen der neuen Werte!
Red=r, Green=g, Blue=b;
sei();
}
//-------------------------------------------------------------------------------
//Timer 0 Interrupt, f/256
//-------------------------------------------------------------------------------
SIGNAL (SIG_OVERFLOW0)
{ static unsigned char PWM_cnt;
#if (INVERT==1)
if (PWM_cnt <Red)
Ledport &=~(1 << R_PIN);
else
Ledport |= (1 << R_PIN);
if (PWM_cnt <Green)
Ledport &=~(1 << G_PIN);
else
Ledport |= (1 << G_PIN);
if (PWM_cnt <Blue)
Ledport &=~(1 << B_PIN);
else
Ledport |= (1 << B_PIN);
#else
if (PWM_cnt <Red)
Ledport |= (1 << R_PIN);
else
Ledport &=~(1 << R_PIN);
if (PWM_cnt <Green)
Ledport |= (1 << G_PIN);
else
Ledport &=~(1 << G_PIN);
if (PWM_cnt <Blue)
Ledport |= (1 << B_PIN);
else
Ledport &=~(1 << B_PIN);
#endif
PWM_cnt++;
if (PWM_cnt==0)
Flags|=Time;
}