关于WS2812
WS2812/2811只需一根信号线就能控制灯带上所有led。多个灯带间可以通过串联轻松延长。在30hz的刷新频率下一个信号线能够控制至多500个led。 WS2812B是我做嵌入式软件的第一个项目,这里资料参考了WS2812灯珠(四)—实现全彩呼吸灯效果,非常感谢这位博主给出的教程和相关源码,但是测试下来有些问题,自己检查修改了一下,在stm32f030f4上可以完美的跑起来。
关于HSV
HSV(Hue, Saturation, Value)是根据颜色的直观特性创建的一种颜色空间, 由 色调(H),饱和度(S),明度(V)三个参数组成,与传统的RGB相比它可以非常方便的通过调整明度来平滑的显示颜色亮度变化.
比较最大最小值的函数
static float min(float a, float b, float c)
{
float m;
m = a < b ? a : b;
return (m < c ? m : c);
}
static float max(float a, float b, float c)
{
float m;
m = a > b ? a : b;
return (m > c ? m : c);
}
RGB转换为HSV
void rgb2hsv(uint8_t g, uint8_t r, uint8_t b, float *h, float *s, float *v)
{
float red, green ,blue;
float cmax, cmin, delta;
red = (float)r / 255;
green = (float)g / 255;
blue = (float)b / 255;
cmax = max(red, green, blue);
cmin = min(red, green, blue);
delta = cmax - cmin;
if(delta == 0)
{
*h = 0;
}
else
{
if(cmax == red)
{
if(green >= blue)
{
*h = 60 * ((green - blue) / delta);
}
else
{
*h = 60 * ((green - blue) / delta) + 360;
}
}
else if(cmax == green)
{
*h = 60 * ((blue - red) / delta + 2);
}
else if(cmax == blue)
{
*h = 60 * ((red - green) / delta + 4);
}
}
if(cmax == 0)
{
*s = 0;
}
else
{
*s = delta / cmax;
}
*v = cmax;
}
HSV转换为RGB
void hsv2rgb(float h, float s, float v, uint8_t *g, uint8_t *r, uint8_t *b)
{
if(s == 0)
{
*r=*g=*b=v;
}
else
{
float H = h / 60;
int hi = (int)H;
float f = H - hi;
float p = v * (1 - s);
float q = v * (1 - f * s);
float t = v * (1- (1 - f) * s);
switch (hi){
case 0:
*r = (int)(v * 255.0 + 0.5);
*g = (int)(t * 255.0 + 0.5);
*b = (int)(p * 255.0 + 0.5);
break;
case 1:
*r = (int)(q * 255.0 + 0.5);
*g = (int)(v * 255.0 + 0.5);
*b = (int)(p * 255.0 + 0.5);
break;
case 2:
*r = (int)(p * 255.0 + 0.5);
*g = (int)(v * 255.0 + 0.5);
*b = (int)(t * 255.0 + 0.5);
break;
case 3:
*r = (int)(p * 255.0 + 0.5);
*g = (int)(q * 255.0 + 0.5);
*b = (int)(v * 255.0 + 0.5);
break;
case 4:
*r = (int)(t * 255.0 + 0.5);
*g = (int)(p * 255.0 + 0.5);
*b = (int)(v * 255.0 + 0.5);
break;
case 5:
*r = (int)(v * 255.0 + 0.5);
*g = (int)(p * 255.0 + 0.5);
*b = (int)(q * 255.0 + 0.5);
break;
default:
break;
}
}
}
|