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;
		}
		
	}


}
	


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部