控制WS2812B实例代码(新_PWM方式)

1.  控制方式

        WS2812B数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit。

 

2. 输入码型

        每一次传数据前,需要先给个复位信号,如下图所示。

        然后依次是每个灯的24bit数据,且写入24bit位数据的排序方式为:G -> R -> B ,如下图所示。


        而每个 bit 位的表示方式为:(高电平+低电平)时间,如下图所示。

 

 

3. 典型电路


4. 部分代码

完整单片机代码:https://download.csdn.net/download/qq_26043945/89657851

#include "WS2812B.h"


uint32_t GRB[]={0x00FF00,0x00FF19,0x00FF32,0x00FF4B,0x00FF64,0x00FF7D,0x00FF96,0x00FFAF,0x00FFC8,0x00FFE1,
								0x00FFFF,0x00E1FF,0x00C8FF,0x00AFFF,0x0096FF,0x007DFF,0x0064FF,0x004BFF,0x0032FF,0x0019FF,
								0x0000FF,0x1900FF,0x3200FF,0x4B00FF,0x6400FF,0x7D00FF,0x9600FF,0xAF00FF,0xC800FF,0xE100FF,
								0xFF00FF,0xFF00E1,0xFF00C8,0xFF00AF,0xFF0096,0xFF007D,0xFF0064,0xFF004B,0xFF0032,0xFF0019,
								0xFF0000,0xFF1900,0xFF3200,0xFF4B00,0xFF6400,0xFF7D00,0xFF9600,0xFFAF00,0xFFC800,0xFFE100,0xFFFF00};							
								
__IO uint32_t WS2812_buf[LED_Num]={0};							
__IO uint32_t GRB_buf[LED_Num]={0};


//用于确定现在传输的是哪一个灯珠的数据
__IO uint32_t ws2812b_num=0;

//用于ws2812灯带的每1灯的24位数据进行提取
__IO uint32_t ws2812b_num_bit=0x800000;

//用于ws2812灯带的复位计数
uint8_t ws2812b_rst_num=0;


void ws2812_close(void){

	ws2812_stop();
	for(uint32_t x=0;x<LED_Num;x++){
		WS2812_buf[x] = 0x000000;
	}
	ws2812_run();
}


void ws2812_stop(void){
	
	ws2812_hal_stop;
	ws2812b_num=0;
	ws2812b_num_bit=0x800000;
	__HAL_TIM_SET_COMPARE(ws2812b_Tim, ws2812b_Channel, 0);
	HAL_Delay(1);
}

void ws2812_run(void){
	
	ws2812_hal_run;
}

void ws2812b_G_R_B_all(uint8_t num, uint8_t brigh){
	
	uint8_t r,g,b;
	
	if(num==0){
		
		g = 0x00ff00/65536;
		r = 0x00ff00%65536/256;
		b = 0x00ff00%256;
		
		for(uint32_t x=0;x<LED_Num;x++){
			WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
		}
			
	}else if(num==1){
		
		g = 0xff0000/65536;
		r = 0xff0000%65536/256;
		b = 0xff0000%256;
		
		for(uint32_t x=0;x<LED_Num;x++){
			WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
		}
	
	}else if(num==2){
		
		g = 0x0000ff/65536;
		r = 0x0000ff%65536/256;
		b = 0x0000ff%256;
		
		for(uint32_t x=0;x<LED_Num;x++){
			WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
		}
	
	}

	
}



void ws2812b_while_all(uint8_t num, uint8_t brigh){
	
	uint8_t size = sizeof(GRB) / sizeof(GRB[0]); // 计算数组长度  
	
	uint8_t r,g,b;

	uint32_t buf = GRB[num%size];
	
	g = buf/65536;
	r = buf%65536/256;
	b = buf%256;

	for(uint8_t x=0;x<LED_Num;x++){
			WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
	}

}


void ws2812b_while_all1(uint8_t num, uint8_t brigh){
	
	uint8_t r,g,b;
	
	uint8_t size = sizeof(GRB) / sizeof(GRB[0]); // 计算数组长度  
  uint32_t buf = GRB[0]; // 保存第一个元素  

	// 将每个元素向前移动一个位置  
	for (uint8_t i = 1; i < size; i++) {  
			GRB[i - 1] = GRB[i];  
	}  

	// 将第一个元素放到最后一个位置  
	GRB[size - 1] = buf;  
	
	for(uint32_t x=0;x<LED_Num;x++){
		
		uint8_t size = sizeof(GRB) / sizeof(GRB[0]); // 计算数组长度  
		
		uint8_t i = x*num%size;
		
		g = GRB[i]/65536;
		r = GRB[i]%65536/256;
		b = GRB[i]%256;
		
		WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
	}
	
}



void ws2812b_while_all2(uint8_t num, uint8_t brigh){
	
	uint8_t r,g,b;
	
	uint8_t size = sizeof(GRB) / sizeof(GRB[0]); // 计算数组长度  
  uint32_t buf = GRB[size - 1]; // 保存最后一个元素  

	// 将每个元素向后移动一个位置  
	for (uint8_t i = size - 1; i > 0; i--) {  
			GRB[i] = GRB[i - 1];  
	}  

	// 将最后一个元素放到第一个位置  
	GRB[0] = buf;  
	
	for(uint32_t x=0;x<LED_Num;x++){
		
		uint8_t size = sizeof(GRB) / sizeof(GRB[0]); // 计算数组长度  
		
		uint8_t i = x*num%size;
		
		g = GRB[i]/65536;
		r = GRB[i]%65536/256;
		b = GRB[i]%256;
		
		WS2812_buf[x] = ((uint8_t)(g*(0.0039*brigh)))*65536+((uint8_t)(r*(0.0039*brigh)))*256+((uint8_t)(b*(0.0039*brigh)));
	}
	
}



void ws2812b_rst(void){
	
	__HAL_TIM_SET_COMPARE(ws2812b_Tim, ws2812b_Channel, 0);
	ws2812b_rst_num++;
	if(ws2812b_rst_num>15){
		ws2812b_rst_num=0;
		ws2812b_num=0;
		for(uint8_t x=0;x<LED_Num;x++){
			GRB_buf[x] = WS2812_buf[x];
		}
		
	}

}

uint32_t ws2812_buf=0;

void ws2812b_set(void){
	
	if(ws2812b_num==LED_Num){
	
		ws2812b_rst();
		
	}else{

		ws2812_buf = GRB_buf[ws2812b_num];
		

		if(ws2812_buf&ws2812b_num_bit){
			ws2812b_set_1;
		}else{
			ws2812b_set_0;
		}
		
		ws2812b_num_bit = ws2812b_num_bit>>1;
		
		if(ws2812b_num_bit==0x000000){
			ws2812b_num++;
			ws2812b_num_bit = 0x800000;
		}
		
	}


}
	


当使用Arduino控制WS2812B LED灯时,您需要使用FastLED库。以下是一个简单的示例代码,演示如何控制WS2812B LED灯的颜色。 首先,确保您已经安装了FastLED库。您可以在Arduino IDE中选择“工具”>“库管理器”,搜索并安装FastLED库。 接下来,将以下代码复制到Arduino IDE中: ```cpp #include <FastLED.h> #define LED_PIN 6 // 定义LED数据引脚 #define NUM_LEDS 10 // 定义LED数量 CRGB leds[NUM_LEDS]; // 创建一个CRGB对象数组,用于存储LED颜色数据 void setup() { FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); // 设置LED类型为WS2812B,数据引脚为LED_PIN,颜色顺序为GRB } void loop() { // 设置LED颜色 for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CRGB(255, 0, 0); // 设置为红色 } FastLED.show(); // 显示LED颜色 delay(1000); // 延迟1秒 // 清除LED颜色 for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CRGB(0, 0, 0); // 关闭LED } FastLED.show(); // 显示清除后的LED状态 delay(1000); // 延迟1秒 } ``` 请确保将LED数据引脚(LED_PIN)和LED数量(NUM_LEDS)设置为与您的电路连接相匹配的值。在上述示例中,我们将LED颜色设置为红色,并在每次循环中打开和关闭LED。 上传代码到Arduino板上,它将开始控制WS2812B LED灯并显示红色。您可以根据需要修改颜色和其他效果。 请注意,这只是一个简单的示例代码,您可以根据自己的需求进行更多的定制和扩展。希望对您有所帮助!如果您有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_755682240

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值