话不多说,先上演示视频:
接下来,详细介绍一下这次的调光之旅。
本次实践的硬件,我选用的是沁恒的CH555 RGB评估板。
Firststep,硬件玩起来,先看手册:

从手册可以看出,CH555内置了RGB三色LED控制器,可以直接驱动普通灯珠RGB灯珠(比起内置驱动芯片的RGB灯珠便宜不少),8*3路PWM用于RGB灯光控制,16路COM口扫描,也就是支持8*16=128组RGB灯。
另外,它支持最高8位色彩PWM模式,每个RGB通道支持256级控制,支持16777216种组合色,这个色域范围基本已经包括了人类视力所能感知的所有颜色。
下面继续看原理图,芯片最小系统原理图如下所示,外围还是非常简单的。

原理图里看到了个比较有意思的设计,通过两个IO控制MOS,每个MOS来控制一组16路COM,这样也就实现了控制(16+16)*8=256组RGB灯,RGB灯的扫描规模扩大了一倍,扫描频率计算了一下,还能达到100Hz左右,这应该算得上是高刷了吧!

芯片支持USB2.0全速接口,将USB接口引出来,便于程序下载,同时也可通过PC连接USB非常方便的更新灯效控制。放全图:

Secondstep,软件调起来。最开始我肯定要把每一个灯都给点起来,那么我就要给每一个灯设定坐标,想让哪个灯亮就让哪个灯亮。CH555有个很大的优势就是它有个专用LED DMA模式,支持从Flash-ROM加载预置的固化数据或者从xRAM加载编辑后的数据,结合硬件设计,软件设置如下:
//需要输入的参数:灯的索引号(0-255)、灯的亮度值、灯的RGB色彩值
void set_led_light(UINT16 led_num,UINT8 led_int,UINT8 led_red,UINT8 led_green,UINT8 led_blue)
{
if(led_num<=127)
{
if(P3_6 == 0&& P3_7 == 1) //刷第一面
{
if(led_num < 96)
{
RGB_DataBuf0[led_num+32][0] = led_int;
RGB_DataBuf0[led_num+32][1] = led_red;
RGB_DataBuf0[led_num+32][2] = led_green;
RGB_DataBuf0[led_num+32][3] = led_blue;
}
else if(led_num>=96&&led_num<128)
{
RGB_DataBuf0[led_num-96][0] = led_int;
RGB_DataBuf0[led_num-96][1] = led_red;
RGB_DataBuf0[led_num-96][2] = led_green;
RGB_DataBuf0[led_num-96][3] = led_blue;
}
RGB_BufAddr = (UINT16)( &RGB_DataBuf0[ 0 ] );
}
else if(P3_6 == 1&& P3_7 == 0)//刷第二面
{
RGB_BufAddr = (UINT16)( &RGB_DataBuf1[ 0 ] );
}
}
else if(led_num>127&&led_num<256)
{
if(P3_6 == 0&& P3_7 == 1) //刷第一面
{
RGB_BufAddr = (UINT16)( &RGB_DataBuf0[ 0 ] );
}
else if(P3_6 == 1&& P3_7 == 0) //刷第二面
{
if(led_num>127&&led_num < 128+96)
{
RGB_DataBuf1[led_num-128+32][0] = led_int;
RGB_DataBuf1[led_num-128+32][1] = led_red;
RGB_DataBuf1[led_num-128+32][2] = led_green;
RGB_DataBuf1[led_num-128+32][3] = led_blue;
}
else if(led_num>=128+96&&led_num<128+128)
{
RGB_DataBuf1[led_num-128-96][0] = led_int;
RGB_DataBuf1[led_num-128-96][1] = led_red;
RGB_DataBuf1[led_num-128-96][2] = led_green;
RGB_DataBuf1[led_num-128-96][3] = led_blue;
}
RGB_BufAddr = (UINT16)( &RGB_DataBuf1[ 0 ] );
}
}
else
{
RGB_BufAddr = (UINT16)( &RGB_DataBuf2[ 0 ] );
LED_INT_ADJ = 0; //输入LED索引号错误,关闭灯
}
}
经过一番折腾,终于实现了想点哪个灯就点哪个灯、想什么颜色就什么颜色的效果。
流水动起来:
感觉灯效还是没有达到预期的效果,那怎么样效果更好看呢?看看色谱找找灵感。
这么多颜色要怎么组合才符合美学逻辑呢?
无意间拖动色谱的滑条,发现颜色组合不是随机分配的,色系是有规律变化的。下面贴一张动图演示一下:
颜色从左到右变化时,RGB的数值变化是有逻辑可循的。逻辑状态可以总结如下:
sta0:{255,0,0}->sta1 : {255,255,0}->sta2 : {0,255,0}->sta3 : {0,255,255}->sta4 : {0,0,255}->sta5 : {255,0,255}->sta0 : {255,0,0},每一组状态之间数据都是从0-255之间递增或者递减。那么,总共有255*6 = 1530种颜色组合。
目前我的板子上共有32*8个灯,我想让我的每一个灯都跑满这些颜色组合,应该怎么去实现呢?
如果每一个灯都是同时的进行相同的颜色转变,那显然是不行的,不够炫酷。我将我板子上的灯划分为32组,将这255*6种颜色组合均匀的32等份,每一组灯赋相应的初值。在软件设置一个5ms的定时器,每进一次定时器都让不同组的灯RGB数据相应递增或者递减,往自身的下一个状态去切换,即在sta0到sta5这6个状态里不停的循环。
这样一来,每组灯都是以不同的颜色但是以相同的规律变化颜色,也都是等间隔的从一个色域往另一个色域转变,不会有颜色的突变,让灯条产生一种生生不息,循环往复的波浪灯效。
至此,调光之旅告一段落。

赵工
13488683602
zhaojh@kw.beijing.gov.cn
欢迎各公众号,媒体转载,申请加白名单秒通过
投稿/推广/合作/入群/赞助/转发 请加微信13488683602