今天我们不点LED,我们点WS2812B

今天我们不点LED,我们点一下WS2812B(其实也算LED)

WS2812B是可编程的RGB灯,也就是说不同于我们之前玩的固定颜色的灯,这个灯是可以通过我们的编程来改变颜色的。

一般的LED是通上电就亮了,但是WS2812B是上电了也不亮,要让它亮,我们需要通过一根数据线给它发送数据才行。

我们给WS2812B发送24bit的数据,也就是3个Byte,高位先发,分别代表GRB(记住顺序),通过设置GBR的数值来调整绿蓝红的大小,从而改变WS2812B的颜色。

然后从上面手册里截来的图我们可以发现,我们一次性可以发很多个3Byte,这是因为我们可以把很多个WS2812B串联起来,这样我们只需要一根数据线就能控制多个WS2812B!

比如我们发送3个3Byte的数据给三个串联起来的WS2812B,第一个3Byte会被第一个灯接收,然后第一个灯会把剩下的两个3Byte传下去。

在原理图里就像是下面这样。

第一个灯的DIN接到我们的MCU的引脚上,然后把第一个灯的DOU接到下一个灯的DIN……最后一个灯的DOU直接接地就行。

然后手册里推荐是WS2812B接个10nf(104)的电容。

接着看看参数,范围还是非常大的,容错空间很大。

我是直接用STC8G1K08A来操控WS2812B的,用的5V供电(3.3V也可以的)。

自己画了块板子,上面集成了STC32和STC8两个芯片,一次性就可以玩到两种单片机,过阵子我第二版测试没问题之后再开源出来。

我在板子上的STC8G1K08A这边直接接了个WS2812B,今天我们就来看看怎么点亮它,只要知道了原理,那么换个芯片也是可以轻松点亮的。

刚刚我们知道了我们只需要一根数据线就可以点亮一堆WS2812B,每个WS2812B要接收3个Byte,3Byte按照GRB的顺序来分配绿红蓝的数值,那么问题就只剩下一个,我们应该如何发送数据?

我们可以看看手册。

我们要发送的不是0就是1,剩下RESET码就是用来区分数据批次的。

比如说我一次性要控制三个灯,然后我要让它们亮个颜色A,那么我就发送3*3个Byte。过了一下子我要让它们换个颜色,那么我就需要发送RESET码,表示我这次发送的数据是新的一批,你可别再把数据往后面送了(因为WS2812B可以串联很多个,并且它们并不知道自己后面究竟串联了多少个)

RESET码就是拉低电平一段时间。

0码和1码都是先拉高电平再拉低电平,唯一的区别就是高低电平的持续时间。

先看RESET码,因为它只需要拉低电平,比较简单,只要我们把数据线拉低超过80us,那么就算是发送了RESET码。

我们可以在发送数据之前发一下RESET码(反正也才80us),也可以在每次发送完数据之后再发送RESET码。

接着是0码和1码。

0码的高电平时间是0.2~0.35us,低电平的时间是0.55~1.2us,然后我们要注意一点,每个码元的之间不能小于0.89us,也就是说我们发送0码或者1码的高低电平的时间加起来要超过0.89us。

我们就用表格中的典型值,高电平给0.3us,低电平给0.6us。

1码和0码差不多,高低电平是顺序一样,都是先高电平后低电平,不一样的是持续时间,持续时间其实也差不多,就是高低电平的时间反过来,所以我们1码的高电平时间定为0.6us,低电平时间定为0.3us。

现在我们知道如何发送三个码元(0码1码RESET码)之后就可以开始敲代码了。

唯一的难点在于我们如何控制时间,因为时间单位是us,甚至ns,ns级别就有点难控制了。

一个办法就是用定时器,另一个土办法,我们直接延时。

因为我用的芯片是STC8,所以可以直接拿他家的烧录程序来获取延时函数。

但是人算不如天算,最低精度是1us。

这也难不倒我,经过我一顿操作和计算,STC8G1K08A的主频为24MHz,一个_nop_()大概耗时是63+ns,其实我计算的结果应该是44ns,因为1/24 000 000 约等于是40ns,但是我拿着40一个_nop_()的结果去写代码,发现好像不对劲,最后定位在了一个_nop_()大概耗时是60+ns。

不过这都不是重点,重点是我们要点亮WS2812B。

所以我们之间说的0.3us那就是需要五个_nop_()来延时,但是以防万一,我用的是四个,比较时间范围是0.2~0.35us。

0.6us就用十个_nop_()就行。

然后RESET码因为80us算是时间比较长的,我们就用STC烧录软件提供的延时代码就行。

具体可以参考下面的代码。包含的头文件是STC8的官方库函数。

#include "STC8G_H_Delay.h"
#include "STC8G_H_GPIO.h"

#define WS2812B_IN P32

// 复位
void WS2812B_SendReset(void) {
    unsigned char data i, j;
    WS2812B_IN = 0;  // 拉低80us
    i = 2;
    j = 219;
    do {
        while (--j)
            ;
    } while (--i);
}

// 发送1码
void WS2812B_SendOne(void) {
    WS2812B_IN = 1;     // 拉高延时1us
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    WS2812B_IN = 0;     // 拉低延时0.3us
    _nop_();_nop_();_nop_();_nop_();
}

// 发送0码
void WS2812B_SendZero(void) {
    WS2812B_IN = 1;     // 拉高延时0.3us
    _nop_();_nop_();_nop_();_nop_();
    WS2812B_IN = 0;     // 拉低延时1us
     _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
// 纯红光
void WS2812B_SendRed(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
}
// 纯绿光
void WS2812B_SendGreen(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
}
// 纯蓝光
void WS2812B_SendBlue(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
}


void main(void) {
    P3_MODE_OUT_PP(GPIO_Pin_2);     // 设置P32为推挽输出

    while (1) {
        WS2812B_SendRed();
        delay_ms(1000);
        WS2812B_SendBlue();
        delay_ms(1000);
        WS2812B_SendGreen();
        delay_ms(1000);
    }
}

我是让WS2812B循环更换红色蓝色绿色三种颜色的灯。

效果还行。

我有个大胆的想法,既然WS2812B可以用一根数据线来操控多个,那我直接做个可以调颜色的发光棒,主控芯片就用STC8G1K08A(成本0.3元),然后多放几个WS2812B上去……

过阵子看看实现一下。

WS2812B彩灯是一种智能LED灯带,常用于装饰和照明场合。其原理图大致可以分为三部分:WS2812B芯片控制电路、数据传输线路和电源电路。 WS2812B芯片控制电路是整个彩灯的核心部分,它由WS2812B RGB LED芯片组成。每个WS2812B芯片内部集成了一个RGB LED和一个控制电路。通过控制电路,我们可以使用数字信号控制RGB LED的亮度和颜色。彩灯中的每一个像素就是一个WS2812B芯片。它的特是每个像素都可以独立控制,并且串联在一起。 数据传输线路是在彩灯中连接WS2812B芯片之间的方式。通常采用串行数据传输的方式,也就是将数据信号按顺序传递给彩灯中的每个像素。在传输过程中,每个像素通过接收到的数据来决定自己的亮度和颜色。数据传输线路需要保持良好的电气性能,以防止信号失真。 电源电路为WS2812B彩灯提供工作所需的电能。WS2812B芯片工作电压为5V,因此电源电路需要提供稳定的5V直流电压。在彩灯中,通常使用电源适配器或者直接与计算机USB接口连接来供电。 总结起来,WS2812B彩灯的原理图主要由WS2812B芯片控制电路、数据传输线路和电源电路组成。通过控制电路和数据传输线路,可以实现对每个像素的亮度和颜色的独立控制。电源电路为彩灯提供稳定的工作电压。这种原理图设计使得WS2812B彩灯可以展现出丰富多彩的效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值