本帖最后由 LIzs6 于 2021-11-10 11:23 编辑
随着近几年“有光胜无光”的喊声越来越高, RGB机械键盘,机箱、板卡甚至内存条都支持RGB调光,玩家们以及工作党都享受着被光芒环绕的感觉。最近博主也玩了一次灯效,主要方案构成:CH555主控MCU,外加256颗普通RGB灯珠。话不多说,先上演示视频。
接下来详细介绍一下这一次的调光之旅。实践的硬件用的是沁恒的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个状态里不停的循环。这样每一组灯都是以不同的颜色但是以相同的规律变化颜色,也都是等间隔的从一个色域往另一个色域转变,不会有颜色的突变,让灯条产生一种生生不息,循环往复的波浪灯效。 至此,调光之旅告一段落,附件是硬件、软件资料,兄弟们可以按需下载。
|
你好,我是小白能请教一下吗?每个rgb灯的位置是怎么确定的呢?方便的话可以回复一下吗?
@NK6108 :是不是步入生三胎的年龄了
键盘我还是爱用传统样式,不喜欢发光的,扎睛儿,变色彩灯就更晃眼,倘若还要加上声效,我就更觉着 花里胡哨 !!