WS2812 RGB灯

13 篇文章 7 订阅

一、简介

WS2812只需要一根信号线就能控制灯的多种颜色的变化,多个灯可以级联,在30hz的刷新频率下一个信号线能够控制至多500个LED。在这里插入图片描述

二、原理

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

三、硬件介绍

1.内置信号整形电路,任何一个像素点收到信号后经过波形整形再输出,保证线路波形畸变不会累加。
2.内置上电复位和掉电复位电路
3.每个像素点的三基色颜色可实现256级亮度显示,完成16777216中颜色的全真彩显示,扫描频率不低于400hz/s
4.串行级联接口,能通过一根信号线完成数据的接收和接码。
5.数据发送速度可达800kbps(相当于1.25us传输一比特数据)

四、通信协议

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

数据码的逻辑实现:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
文档部分参考这位作者:
https://blog.csdn.net/tangxing1212/article/details/42964417

五、程序

调试延迟的时候可以用小马哥视频的方法
这里给出链接。
https://www.bilibili.com/video/BV1Qs41137dk/?spm_id_from=333.788.videocard.0



Ws2812.h

#ifndef WS2812
#define WS2812

#define RGB_Port_RCC RCC_APB2Periph_GPIOB //RGB时钟
#define RGB_PIN GPIO_Pin_9 //RGB引脚
#define RGB_PORT GPIOB //RGB端口

#define RGBLED PBout(9)  //RGB灯

// 发送0x000000是关闭灯

void RGB_Init(void); // RGB初始化IO管脚
void RGB_ColorSet(uchar red,uchar green,uchar blue); // 设置一个灯的颜色
void RGB_RandomColor(void); // 产生随机数颜色
void RGB_RandomColor4(void); // 4个灯产生随机的颜色
#endif


Ws2812.c

#include "All.h"

// RGBLED 管脚初始化
void RGB_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RGB_Port_RCC,ENABLE);//系统时钟使能
	
	GPIO_InitStructure.GPIO_Pin = RGB_PIN; //定义管脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//管脚输出模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//管脚的速度
	GPIO_Init(RGB_PORT,&GPIO_InitStructure); //初始化端口

}

// 信号0 300ns高电平  900ns低电平
void RGB_Write0(void)
{
	uchar cnt1=1,cnt2 = 5;
  RGBLED = 1;   // 高电平
	while(cnt1--)  // 300ns
		__nop();
	
	RGBLED = 0;
	while(cnt2--)  // 900ns
		__nop();
}

// 信号1  600ns高电平  600ns低电平
void RGB_Write1(void)
{
	uchar cnt1=3,cnt2 = 3;
  RGBLED = 1;   // 高电平
	while(cnt1--)  // 600ns
		__nop();
	
	RGBLED = 0;
	while(cnt2--)  // 600ns
		__nop();	
}
// 复位   80us低电平
void RGB_LEDReset()
{
	RGBLED = 0;
	delay_us(80);
}


// RGB写一个字节
void RGB_WriteByte(uchar dat)
{
  uchar i;
	for(i= 0;i<8;i++)
	{
		dat <<= i;
	  if(dat & 0x80) // 判断最高位
		{
		   RGB_Write1(); // 写1
		}
		else
		{
		   RGB_Write0(); // 写0
		}
	}
}

// 设置一个灯的颜色
void RGB_ColorSet(uchar red,uchar green,uchar blue)
{
	// 灯的实际写入颜色是GRB
	RGB_WriteByte(green);  // 写入绿色
	RGB_WriteByte(red); // 写入红色
	RGB_WriteByte(blue); // 写入蓝色
}


// 产生一个随机的颜色
void RGB_RandomColor(void)
{
   uchar red,green,blue; 
	// srand((int)time(0)); // 设置随机种子
	 red = rand() % 255; //产生随机数在一个字节的范围内
	 green = rand() % 255;
	 blue = rand() % 255;
	 RGB_ColorSet(red,green,blue); // 合成颜色
}

/* 4个灯各自产生随机的颜色*/
void RGB_RandomColor4(void)
{
  	RGB_RandomColor();   // 产生随机颜色
		RGB_RandomColor(); 
		RGB_RandomColor(); 
		RGB_RandomColor(); 
}
  • 13
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个用C语言编写的WS2812 RGB带控制例程代码。以下是代码: #include <stdint.h> #include <stdio.h> #define LED_COUNT 12 #define LED_PIN 7 void sendBit(uint8_t bit){ if(bit){ // Send '1' bit. 70% ON, 30% OFF TCCR0A = _BV(WGM01) | _BV(COM0A1) | _BV(COM0A0); _delay_us(22); // Clear output TCCR0A = 0; _delay_us( 38); } else { // Send '0' bit. 30% ON, 70% OFF TCCR0A = _BV(WGM01) | _BV(COM0A1) | _BV(COM0A0); _delay_us( 9); // Clear output TCCR0A = 0; _delay_us( 81); } } void sendByte(uint8_t byte){ for(uint8_t i=0;i<8;++i){ sendBit(byte&0x80); byte<<=1; } } void sendColor(uint8_t r,uint8_t g,uint8_t b){ sendByte(g); sendByte(r); sendByte(b); } void sendBuffer(uint8_t *ptr){ for(uint8_t i=0;i<LED_COUNT;++i){ sendColor(ptr[3*i+0],ptr[3*i+1],ptr[3*i+2]); } } void led_init(){ TCCR0A = _BV(WGM01); // Toggle OC0A on compare match TCCR0B = _BV(CS00); // No prescaler DDRD |= _BV(DDD6); // PD6 as output TCCR0A = 0; // Clear output } void led_on(){ TCCR0A = _BV(COM0A1) | _BV(COM0A0); // Set output high } void led_off(){ TCCR0A = 0; // Set output low } void setLedColor(uint8_t *buffer){ cli(); led_on(); _delay_us(60); sendBuffer(buffer); _delay_us(60); led_off(); sei(); } int main(){ uint8_t buffer[LED_COUNT*3]; led_init(); // Initialize timer for 800kHz PWM output while(1){ // Set all LEDs to red for(uint8_t i=0;i<LED_COUNT;++i){ buffer[3*i+0] = 255; // Red buffer[3*i+1] = 0; // Green buffer[3*i+2] = 0; // Blue } setLedColor(buffer); // Send the buffer to the LEDs _delay_ms(500); // Wait half a second // Set all LEDs to green for(uint8_t i=0;i<LED_COUNT;++i){ buffer[3*i+0] = 0; // Red buffer[3*i+1] = 255; // Green buffer[3*i+2] = 0; // Blue } setLedColor(buffer); // Send the buffer to the LEDs _delay_ms(500); // Wait half a second // Set all LEDs to blue for(uint8_t i=0;i<LED_COUNT;++i){ buffer[3*i+0] = 0; // Red buffer[3*i+1] = 0; // Green buffer[3*i+2] = 255; // Blue } setLedColor(buffer); // Send the buffer to the LEDs _delay_ms(500); // Wait half a second } return 0; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值