WS2812 RGB灯
文章目录一、简介二、原理三、硬件介绍四、通信协议五、程序一、简介WS2812只需要一根信号线就能控制灯的多种颜色的变化,多个灯可以级联,在30hz的刷新频率下一个信号线能够控制至多500个LED。二、原理WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高
一、简介
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();
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)