打印
[开发工具]

【新定义MCU开发板测评】WS2812B炫彩灯环控制

[复制链接]
734|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 HonestQiao 于 2022-11-20 00:14 编辑

#申请原创#
我有一个宝贝WS2812B灯环,玩过的板子,我都要给点亮一番。



一、WS2812B控制信号了解:

WS2812B的具体介绍,这里就不详细说明了,在网上,有大量的文章资料进行说明。
要点亮WS2812B,重点在于理解以下要点:
  • WS2812B是通过单总线控制的,也就是一根信号线,控制所有的LED
  • WS2812B每收到一个特定的信号时,会认为收到了0码或者1码:信号总线上,高电平保持1s,低电平保持0.25s,则认为收到了1码;反之,如果高电平保持0.25s,低电平保持1s,则认为收到了0码。
  • 每8个0/1码,对应一种颜色控制,我们可以理解为1个8位二进制,所以范围为0~255;一颗LED,共有三种颜色,接受顺序为GRB,每种颜色取值范围在0~255,十六进制0x00~0xFF;也就是控制一颗灯珠,需要3组8个的0/1码,一个24个0/1码
  • 如果要控制多颗灯珠,则连续发送多组上述数据即可;及时某颗灯珠熄灭,也需要发送对应的0码,使其不亮。
  • 如果要多次发送控制数据,则两次之间,需要低电平保持至少50us

了解了以上信息,我们就可以考虑使用NBK-RD8x3x核心开发板来进行控制。

二、NBK-RD8x3x核心开发板能否满足要求:
从上面的说明,可以看到WS2812B对信号时序有特定的要求,这就需要我们的控制板能够满足这些要求。
进过一番测试,确认在NBK-RD8x3x核心开发板上,直接通过控制IO接口的高低电平,即可满足要求。

通过官方资料了解到:RD8T36 系列具有超高速 1T 8051 CPU 内核,运行频率高达 32MHz。
那么,如果运行在32MHz,则每一个时钟周期的时间为:T0=1/fsoc=1/32MHz=0.03125us
WS2812B要求的最小控制时间细腻度为0.25us,也就是8个T0,因为 0.25us / T0 = 0.25us / 0.03125us = 8.

在C51上,使用1个nop(),就表示一次时钟周期,那么使用8次nop(),就能够实现0.25us的时间控制了。

做好了以上前期准备工作,我们就可以开始正式的工作了。

三、连线:

在NBK-RD8x3x核心开发板的核心开发板上,有两排共4组Arduino管脚,具体如下:


我使用的WS2812B灯环,有DIN和OUT两个接口,控制信号从DIN接入,OUT用于级联下级。
DIN上有三根线,就接到Arduino管脚上,包括5V、GND和信号控制引脚。信号控制引脚,选择了D8。

从官方提供的电路原理图,可以了解到D8具体对应的IO口:


从上图中,可以了解到D8对应的IO口为P06。

最终实物连接如下:


四、代码编写:

万事俱备,只欠代码。

具体的代码如下:WS2812B_Init.c
#include "H/Function_Init.H"
#include <intrins.h>

#define NOP                                                                    \
  {                                                                            \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
    _nop_();                                                                   \
  }
#define LOW 0
#define HIGH 1
#define DIN P06
#define NUM 24

//拉低DIN保持50us以上
void ws2812_init() {
  uchar i;
  DIN = LOW;
  for (i = 0; i <= 200; i++) {
    NOP;
  }
}

//高电平0.25us,低电平1us
void ws2812_write_0() {
  DIN = HIGH;
  NOP;
  DIN = LOW;
  NOP;
  NOP;
  NOP;
  NOP;
}

//高电平1us,低电0.25us
void ws2812_write_1() {
  DIN = HIGH;
  NOP;
  NOP;
  NOP;
  NOP;
  DIN = LOW;
  NOP;
}

void ws2812_write_24bits(unsigned long dat) {
  uchar t[NUM] = {0};
  uchar i;

  for (i = 0; i < NUM; i++) {
    if (dat >> i & 1) {
      t[i] = HIGH;
    } else {
      t[i] = LOW;
    }
  }
  for (i = 0; i < NUM; i++) {
    if (t[i]) {
      ws2812_write_1();
    } else {
      ws2812_write_0();
    }
  }
}

void WS2812B_Test() {
  unsigned int i = 0;
  unsigned int j = 0;
  unsigned int index = 1;
  unsigned long colors[8] = {0x000000, 0xff0000, 0x00ff00, 0x0000ff,
                             0xffff00, 0xff00ff, 0x00ffff, 0xffffff};

  ws2812_init();
  while (1) {
    for (i = 0; i < NUM; i++) {
      if (index % NUM == i) {
        ws2812_write_24bits(colors[index % 7 + 1]);
      } else {
        ws2812_write_24bits(colors[0]);
      }
    }
    index++;
    if (index >= NUM) {
      index = 0;
    }

    for (j = 0; j <= 5; j++) {
      for (i = 0; i <= 4000; i++) {
        NOP;
      }
    }
  }
}



上述代码关键说明:
  • #define NOP:用于定义8个nop()调用,获得0.25us时间占用
  • ws2812_init():提供50us以上低电平保持
  • ws2812_write_0():输出0码
  • ws2812_write_1():输出1码
  • ws2812_write_24bits():根据颜色值,输出24位的0/1码
  • WS2812B_Test():测试主逻辑程序
  • colors: 使用到的颜色值定义

代码中,还用到了index变量,通过其控制当前应该点亮第几颗灯珠,并使用其对7取余,从而则colors中选用对应的颜色。

然后,在main.c中调用即可,具体如下:


最后,编译下载,WS2812B灯环,就会欢快的跳跃起来:


90af01ff621c1c0db487fd435ffdd091 (525.53 KB )

90af01ff621c1c0db487fd435ffdd091

使用特权

评论回复
沙发
lzbf| | 2023-2-7 20:25 | 只看该作者
这个定时器直接操作 的吗?              

使用特权

评论回复
板凳
benjaminka| | 2023-2-7 20:46 | 只看该作者
这个最大可以驱动多少个WS2812B?

使用特权

评论回复
地板
nomomy| | 2023-2-7 21:10 | 只看该作者
WS2812B的时序还是比较严格

使用特权

评论回复
5
updownq| | 2023-2-7 21:45 | 只看该作者
可以移植arduino的库过来的吗?

使用特权

评论回复
6
cashrwood| | 2023-2-7 21:59 | 只看该作者
可以使用spi控制的吗?              

使用特权

评论回复
7
weifeng90| | 2023-2-10 08:41 | 只看该作者
RGB灯就是炫酷啊

使用特权

评论回复
8
uiint| | 2023-3-7 21:04 | 只看该作者
怎么通过定时器实现1us的延时呢?

使用特权

评论回复
9
geraldbetty| | 2023-3-7 21:23 | 只看该作者
直接定时器控制WS2812B可靠吗?

使用特权

评论回复
10
caigang13| | 2023-3-7 21:30 | 只看该作者
WS2812被玩出彩了啊,各种DIY产品。

使用特权

评论回复
11
lzbf| | 2023-3-7 21:39 | 只看该作者
此驱动器可以驱动多少个WS2812B?

使用特权

评论回复
12
albertaabbot| | 2023-3-9 13:28 | 只看该作者
WS2812B的功耗特别大,还是通过专用的驱动电路吧。

使用特权

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

本版积分规则

33

主题

85

帖子

2

粉丝