打印
[国产单片机]

一段奇妙的调光之旅

[复制链接]
35062|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LIzs6|  楼主 | 2021-11-8 09:41 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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个状态里不停的循环。这样每一组灯都是以不同的颜色但是以相同的规律变化颜色,也都是等间隔的从一个色域往另一个色域转变,不会有颜色的突变,让灯条产生一种生生不息,循环往复的波浪灯效。
至此,调光之旅告一段落,附件是硬件、软件资料,兄弟们可以按需下载。

CH555_RGB_SHOW.rar

2.06 MB

使用特权

评论回复
评论
winter0110 2023-11-28 19:40 回复TA
你好,我是小白能请教一下吗?每个rgb灯的位置是怎么确定的呢?方便的话可以回复一下吗? 
地瓜patch 2021-12-11 08:33 回复TA
@NK6108 :是不是步入生三胎的年龄了 
NK6108 2021-11-24 00:25 回复TA
键盘我还是爱用传统样式,不喜欢发光的,扎睛儿,变色彩灯就更晃眼,倘若还要加上声效,我就更觉着 花里胡哨 !! 

相关帖子

沙发
单模先声| | 2021-11-8 10:11 | 只看该作者
这开源精神真棒

使用特权

评论回复
板凳
Archer0911| | 2021-11-9 11:24 | 只看该作者
如果把RGB灯换成单色灯,LED灯的驱动规模又可以翻三倍:8x32x3 = 768 颗,亮度每颗独立可调,可以当做图形显示面板来用了

使用特权

评论回复
地板
虚空大人| | 2021-11-10 09:21 | 只看该作者
楼主牛X

使用特权

评论回复
5
努力反击| | 2021-11-11 11:24 | 只看该作者
学到了

使用特权

评论回复
6
ningling_21| | 2021-11-11 19:56 | 只看该作者
感谢楼主分享

使用特权

评论回复
7
coody| | 2021-11-12 11:48 | 只看该作者
类似功能我用STC8G2K64S4 LQFP48也做过,电路类似,这个IC有45路15位的PWM,我用其中24路PWM,设置为8位PWM,驱动8个RGB或24个单色LED,8个IO做COM驱动,4个IO选择4组COM(只需要12个MOSFET),就是32个COM,跑24.576MHz,PWM时钟为主频/50,则LED刷新周期=24576000/50/256/32=60Hz,要在PWM周期中断中处理COM和装载PWM值,768个颜色放在显示数组中。

使用特权

评论回复
8
yljon| | 2021-11-12 15:12 | 只看该作者
好看的很

使用特权

评论回复
9
trucyw| | 2021-11-16 17:09 | 只看该作者
挺不错的哦

使用特权

评论回复
10
单片机小哥| | 2021-11-16 19:04 | 只看该作者
为楼主的大公无私分享的精神点赞

使用特权

评论回复
11
wyyyy| | 2021-11-17 18:51 | 只看该作者
不错不错,灯效看着很nice

使用特权

评论回复
12
深秋王| | 2021-11-19 14:27 | 只看该作者
不错,牛人

使用特权

评论回复
13
鑫越电子| | 2021-11-21 10:36 | 只看该作者
感谢楼主的分享

使用特权

评论回复
14
hi0712| | 2021-11-24 14:41 | 只看该作者
什么鬼

使用特权

评论回复
15
493326732| | 2021-11-27 12:55 | 只看该作者
楼主niux啊  厉害

使用特权

评论回复
16
人生路上路生人| | 2021-11-27 23:44 | 只看该作者
为啥下载不了呀?

使用特权

评论回复
17
linuxke| | 2021-11-28 11:02 | 只看该作者
CH555在哪买

使用特权

评论回复
18
一路向北lm| | 2021-12-1 17:11 | 只看该作者
开源真好

使用特权

评论回复
19
novel2021| | 2021-12-2 16:09 | 只看该作者
不错!

使用特权

评论回复
20
星业发达88| | 2021-12-3 15:29 | 只看该作者
很好看

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

96

帖子

2

粉丝