WS2812B灯带

这篇具有很好参考价值的文章主要介绍了WS2812B灯带。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 开发WS2812B灯带笔记


目录

什么是WS2812B灯

WS2812B灯带连接原理图

WS2812B灯带的数据和数据传输是啥样的?

补充:什么是RGB?

那么WS2812B灯的24bit数据如何构造?

WS2812B灯的逻辑“1”和逻辑“0”

代码部分

实现ns级别延时


什么是WS2812B灯

WS2812B是一种智能控制LED光源,将控制电路和RGB芯片集成在5050个元件包中。其内部包括智能数字端口数据锁存器和信号重塑放大驱动电路。还包括精密内部振荡器和电压可编程恒流控制部分,有效地确保像素点光色高度一致。俗称IC灯。

WS2812B灯带连接原理图

WS2812B灯带

主要通过一条数据线来控制每个灯的颜色 ,每个灯珠控制着下个灯珠。

WS2812B灯带的数据和数据传输是啥样的?

WS2812B灯带

数据传输协议采用单一的NZR通信模式。在像素通电复位后,DIN端口从控制器接收数据,第一个像素收集初始24位数据,然后发送到内部数据锁存器,其他数据通过内部信号重塑放大电路的重塑,通过DO端口发送到下一个级联像素。在对每个像素进行传输后,该信号减少24位。像素采用自动整形传输技术,使像素级联数不限制信号的传输,只依赖于信号传输的速度。

通俗点讲,就是每个灯接受24位的数据为每个灯的颜色像素(RGB888)。比如,你发送了3组24位的数据,第一个灯珠接收了第一组24位数据后,会把后面的两组数据发给第二个灯珠,第二个灯珠接受了第二组24位数据后,会把第三组数据发给第三个灯珠,以此类推。

灯珠接受的24位数据按图里来看,是8位绿色,8位红色,8位蓝色组成。

补充:什么是RGB?

RGB颜色空间以R(Red:红)、G(Green:绿)、B(Blue:蓝)三种基本色为基础,进行不同程度的叠加,产生丰富而广泛的颜色,所以俗称三基色模式。

RGB空间是生活中最常用的一个颜色显示模型,电视机、电脑的CRT显示器等大部分都是采用这种模型。自然界中的任何一种颜色都可以由红、绿、蓝三种色光混合而成,现实生活中人们见到的颜色大多是混合而成的色彩。

肉眼可以识别世界上的所有颜色,而RGB几乎可以组合成世界上所有的颜色!

以我们所用的RGB24为例,RGB24的每个元素在计算机内存中占用1个字节,1个字节等于8个bit位,所以RGB每个元素的取值范围为:0~255。

那么三色组合起来256x256x256=16777216(一千六百七十七万七千二百一十六)种颜色。

那么WS2812B灯的24bit数据如何构造?


既然是24bit数据代表三种颜色,我们就要首先知道一个bit的意义是什么,我们传统意义上来说1个bit代表一个数据位,但是对于数据位bit的理解好像就是“1”或者“0”在数电里我们很容易把高低电平跟逻辑1和逻辑0对应起来,但是表示灯珠的逻辑电平不是简单的高低电平。在数值上0xFFFFFF就是24bit的1,0x000000就是24bit的0.这里有8个bit代表颜色G分量,G7G6G5G4G3G2G1G0,有8个bit代表R分量R7R6R5R4R3R2R1R0,有8个bit代表B分量B7B6B5B4B3B2B1B0,当不同分量组合时候就会有不同的数据产生,这个数据背后其实是逻辑电平。

但是我们IC灯的逻辑“1”并不是简简单单的高电平,IC灯的逻辑“0”也不是简简单单的低电平。

WS2812B灯的逻辑“1”和逻辑“0”

WS2812B灯带

 从上图可知,逻辑“1”和逻辑“0”并不是普通的高电平,低电平。而是由高低电平不同比例组成的。

逻辑“0”:由小部分的高电平和大部分的低电平组成 

逻辑“1”:由大部分的高电平和小部分的低电平组成

下面讲讲这大部分和小部分的精确取值:WS2812B灯带

 逻辑“0”:由220ns-380ns的高电平和580ns-1us的低电平组成

逻辑“1”:由由220ns-380ns的低电平和580ns-1us的高电平组成

代码部分

到这我们差不多就知道了WS2812B灯的原理和时序了,下面讲讲编程的部分。

实现ns级别延时

  1. 硬件延时NOP实现
  2. 滴答定时器中断实现
  3. 普通定时器实现

首先因为对时序要求比较严格,所以需要实现ns级别的延时。

我用的板子是gd32f450,系统频率是200mhz。

1/200Mhz = 0.005 ms = 5 ns

所以一个nop的延时是5ns。

#define DELAY_5ns	__NOP() /* 一个nup为5ns		1/200Mhz = 0.005 ms = 5 ns*/
#define DELAY_50ns  DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns;DELAY_5ns
#define DELAY_250ns	DELAY_50ns;DELAY_50ns;DELAY_50ns;DELAY_50ns;DELAY_50ns
#define DELAY_300ns	DELAY_50ns;DELAY_50ns;DELAY_50ns;DELAY_50ns;DELAY_50ns;DELAY_50ns
#define DELAY_600ns	DELAY_300ns;DELAY_300ns

编写逻辑“0”和逻辑“1”的函数

void Bit_0(void)
{
	rt_pin_write(IC_LED_GREEN_REG,1);
	DELAY_300ns;
	rt_pin_write(IC_LED_GREEN_REG,0);
	DELAY_600ns;
}
void Bit_1(void)
{
	rt_pin_write(IC_LED_GREEN_REG,1);
	DELAY_600ns;
	rt_pin_write(IC_LED_GREEN_REG,0);
	DELAY_300ns;
}

最简单的驱动函数

void RGB_Set(void)
{
	for(uint8_t i = 0;i<8;i++)
	{
		Bit_1();
	}
	for(uint8_t i = 0;i<8;i++)
	{
		Bit_0();
	}
	for(uint8_t i = 0;i<8;i++)
	{
		Bit_0();
	}
}

这样就生成了24bit的数据,111111110000000000000000,绿灯

但是这样的操作方法显然不适合在项目里使用,所以我们要写一些函数来设置

比如我们一般是按RGB值来设定灯的颜色,我们输入RGB三颜色的值就可以。但是这样的话又会又一个问题,我们输入的是10进制的值,0-255。但是我们所需要的却是需要把这个值换成2进制,因此,需要根据这些来编写代码

首先需要控制函数,以后项目需要控制IC灯只需要调用这个函数输入相对应的RGB值就行了,

int ic_led_ctrl(int r_val, int g_val, int b_val) 
{
	decimal_to_binary(r_val,g_val,b_val);
	
	return 0;
}

接着我们要实现把10进制的RGB值转化为2进制的RGB值

/* 连接数组 */
int connection_arr(int *r,int *g,int *b)
{
    int i = 1;
    int *rgb = rgb_arr;
	while (i <= 8)
	{
		*rgb = *g;
		rgb++;
		g++;
		i++;
	}

    while (i <= 16)
	{
		*rgb = *r;
		rgb++;
		r++;
		i++;
	}

    while (i <= 24)
	{
		*rgb = *b;
		rgb++;
		b++;
		i++;
	}
	
	return 0;
}

/* 反转数组 */
int reverse(int *x) {
    int* p, temp, * i, * j;
	int	m = (8 - 1) / 2;
	
    i = x;    		/* 数组首元素地址 */
    j = x + 8 - 1;	/* 数组末尾元素地址 */
    p = x + m;		/* 中间元素地址 */
    
    for (i = x; i <= p; ++i, --j) {
        temp = *i;
        *i = *j;
        *j = temp;
    }
	
    return 0;
}
/* 十进制转换成二进制 */
static void decimal_to_binary(int r_num,int g_num, int b_num)
{

        int r_arr[8] = {0}; /* 用一个长度为32的数组接收最后的二进制数,里面的0是为数组设置初始值 */
        int g_arr[8] = {0};
        int b_arr[8] = {0};

        int index = 0;/* 用来定义数组的下标 */
        
		r_arr[index] = r_num % 2; /* 先获取输入数字的第一个二进制位 */
        g_arr[index] = g_num % 2;
        b_arr[index] = b_num % 2;
        index++; /* 下标下移一位 */
        
        while (1) {/* 使用while循环来获取剩下的二进制位 */
			/*十进制转换为二进制思想:
			 1.对十进制数进行除以2的操作
             2.对所获得的商进行取余的操作,所获得的数就是二进制每一位
             3.当num<2时,即num除以二不会再有大于1的数字,num%2必为0时
             此时说明num已经完全转换位二进制数,则跳出循环*/
			r_num = r_num / 2;
			g_num = g_num / 2;
            b_num = b_num / 2;
			
            r_arr[index] = r_num % 2;
            g_arr[index] = g_num % 2;
            b_arr[index] = b_num % 2;
            index++;
			
            if (g_num < 2 && r_num <2 && b_num < 2){
                break;
            }			
        }		
		reverse(r_arr);
		reverse(g_arr);
		reverse(b_arr);
		connection_arr(r_arr,g_arr,b_arr);
}

十进制转换二进制代码详解,请点击观看

当做完上面这些,我们只需要在主函数中写入RGB的值就能实现灯带的点亮了。

void RGB_Set(void)
{
	int i = 0;
	
	for(i = 0; i < 24; ++i) {
		if(rgb_arr[i] == 1)
		{
			Bit_1();
		} else {
			Bit_0();
		}
	}
	
}

上述方法为简单驱动灯带,在项目开发过程中会遇到一些问题难以解决,因此有了下面一种方法:timer+pwm+dma的方式驱动灯带,如有兴趣,请移步下一篇文章。 

下一篇,timer+pwm+dma驱动ws2812,请点击此处

 感谢阅读文章来源地址https://www.toymoban.com/news/detail-471264.html

到了这里,关于WS2812B灯带的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WS2812B彩灯 STM32HAL库开发:PWM+DMA(stm32f103c8t6)

    目录 一、摘要 二、WS2812B介绍 三、CUBEMX配置 四、程序介绍(KEIL编译器) 五、数据手册         1、本文使用示例单片机型号为 stm32f103c8t6 ,RGB型号为 WS2812B ;          2、主要实现功能是实现用 PWM+DMA 使RGB_LED亮起不同颜色的灯光;         3、目的:简单调通该型号

    2024年02月03日
    浏览(38)
  • GPIO模拟时序控制外设1——WS2812B

    上一篇文章中介绍了整个板子的最基本功能模块——使用GPIO的通用输入输出实现简单的按键输入以及推挽输出控制的功能。本文深入一步,在只使用GPIO的输入输出功能的基础上,通过查看对应模块的芯片手册,模拟其对应的通信时序来驱动对应的模块。 首先来个网红模块—

    2024年02月12日
    浏览(35)
  • 【Arduino】ESP8266&WS2812S灯带控制

    前言   关于WS2812S灯带的驱动控制时序,网上已经有很多文章介绍过,这里就不在介绍了。这里只是为有WS2812S灯带的时候,能快速应用起来。直接举例代码案例,适合个人笔记用。 目录 下载文件 代码案例 下载文件   左上角点击 工具 ,在下拉的选项中,选 管理库 ,搜

    2024年02月13日
    浏览(28)
  • 【ESP32 IDF】用RMT控制 WS2812 彩色灯带

    在上一篇中,老周用 .NET Nano Framework 给大伙伴们演示了 WS2812 灯带的控制,包括用 SPI 和 红外RMT 的方式。利用 RMT 是一个很机灵的方案,不过,可能很多大伙伴对 ESP32 的 RMT 不是很熟悉。除了乐鑫自己的文档,没几个人写过相关的水文,可见这里头空白的水市场很充足,老周

    2024年04月22日
    浏览(53)
  • 【Nano Framework ESP32篇】WS2812 彩色灯带实验

    地球人皆知,许多物联网教程作者的心中都深爱着一灯大师,所以第一个例程总喜欢点灯,高级一点的会来个“一闪一闪亮晶晶”。老周今天要扯的也是和灯有关的,但不单纯地点个灯,那样实在不好玩,缺乏乐趣。老周打算舞个龙灯,哦不,是用 LED 彩色灯带给伙伴们整点

    2024年04月17日
    浏览(44)
  • 【花雕动手做】ASRPRO语音识别(33)--语音驱动8位 WS2812B直条

    WS2812B芯片 是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部振荡器和12V高压可编程定电流控制部分,有效保证了像素点光

    2024年01月17日
    浏览(35)
  • STM32例程分享-05-WS2812B灯带(单线归零码)

    例程运行结果:    WS2812B是一款全彩LED控制IC,单总线控制, 灯带上的每一位灯珠都可用编程控制全彩显示,通过单片机,我们可以实现任意数量任意颜色任意组合效果的炫彩灯光显示效果。    数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制

    2024年02月11日
    浏览(28)
  • STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)

    博主使用STM32驱动WS2812B主要参考了这位佬的文章,因为需求问题,采用了Cortex-M0的stm32f030f4p6(16k的flash,4k的sram)来驱动,原文中写的是stm32f103c8t6,个人认为其实区别并不是很大,需要修改部分参数即可移植(cv战士申请出战)。 上图是我的一圈灯,一共8个,第一个LED的数

    2024年02月06日
    浏览(53)
  • (STM32笔记5)ws2812驱动开发

    ws2812 需要开发的外设:ws2812 开发环境:MDK 开发板:stm32最小系统板 杜邦线无数 一、原理阐述 (一) 这个ws2812有很多种,一个小灯、灯带,矩形像素屏等等。 这些都是DIN连接输入,DOUT连接输出,另外两个引脚是GNE和VCC   (二) 数据传输原理: 第1个WS2812B灯珠接收到了第1个

    2024年01月19日
    浏览(36)
  • 软件STM32cubeIDE下STM32F1xx使用定时器(TIM8)+DMA+PWM点亮灯带WS2812-基础样例

    好长时间不调试灯带ws2812了,最近项目上,要在STM32F1上进行点灯带ws2812,虽然自己之前做了很多了,但是人有个性质,一旦某个事情做完了,你不在去惦记它了,基本会完全抛在脑后。所以才体现记录的重要性,本次在做STM32F1上验证时,即使之前有经验的情况下,还是掉坑

    2024年02月01日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包