一、WS2811简介
输出端口耐压12V
芯片内置稳压管,24V以下电源端只需串电阻IC到VDD脚,无需外加稳压管
灰度调节电路(256级灰度可调)
内置信号整形电路,任何一个IC收到信号后经过波形整形后在输出,保证线路波形畸变不会累加
内置上电复位和掉电复位电路
PWM控制端能够实现256级调节,扫描频率不低于400HZ/S
串行接口级联,一根信号线DI完成数据的接收与解码
任意两点传输距离不超过2米无需增加任何电路
当刷新速率30帧/秒时,低速模式级联数不小于512点,高速模式下不小于1024点
数据发送速度可达与400Kbps与800Kbps两种模式

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

WS2811 0码、1码、reset码时序、串接方法

数据传输
需要精确延时的,使用示波器进行查看

三、电路连接

图出处:天际智联STM32F103开源四轴
四、开源代码
WS2811.h
#ifndef __WS2811_H
#define __WS2811_H
#include <stm32f10x.h>
//#define Time_D 400 //宏定义
#define nWs 50 // 定义串接级联WS2811个数 50可修改
//B-R-G 定义颜色24bits
#define White 0xFFFFFF // 白色
#define Black 0x000000 // 黑色 (不亮)
#define Blue 0xFF0000 // 蓝色
#define Red 0x00FF00 // 红色
#define Green 0x0000FF // 绿色
#define Gray 0x22ee22
extern void WS_GPIO_Init(void);//WS2811端口初始化
extern unsigned long WsDat_RUN[nWs];//流水灯显存
extern unsigned long WsDat[nWs];//流水灯显存
//extern void WS_Reset(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin); //复位
//extern void WS_Set1(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long dat);
//发送1个字节
extern void WS_Set_Date(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned char len,unsigned long dat); //发送相同数据
extern void WS_SetAll(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN); //发送所有字节
//灯带控制方案
extern unsigned long ColorToColor(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color0, unsigned long color1,unsigned int speed) ;//颜色渐变
//初始化显存数组
extern void LED_Init(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color); extern void RUN_LED(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color,unsigned int speed,unsigned char temp); //跑马灯
#endif
WS2811.C
#include "WS2811.h"
unsigned long WsDat[nWs]; //显存
unsigned long WsDat_RUN[nWs]; //流水灯显存
/**************************************************
* IO初始化(移植时请修改)
***************************************************/
void WS_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE ); //端口时钟,使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; // PIN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); // 端口配置,根据设定参数初始化
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12; // PIN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); // 端口配置,根据设定参数初始化
}
/**************************
* 内部延时
***************************/
void WS_delay_us(__IO u32 nCount) //简单的延时函数
{
for(; nCount != 0; nCount--);
}
void WS_delay2us()
{
unsigned char i;
for(i=0; i<11; i++);
}
void WS_delay05us()
{
// unsigned char i;
// for(i=0; i<1; i++);
}
void WS_delay_ms(uint32_t nms)
{
while(nms--)
{
WS_delay_us(1670); //普通方式延时
}
}
/***************************
* 发送一比特
****************************/
void TX0(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) // 发送0
{
GPIO_SetBits(GPIOx, GPIO_Pin);
WS_delay05us();
GPIO_ResetBits(GPIOx, GPIO_Pin);
WS_delay2us();
}
void TX1(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) // 发送1
{
GPIO_SetBits(GPIOx, GPIO_Pin);
WS_delay2us();
GPIO_ResetBits(GPIOx, GPIO_Pin);
WS_delay05us();
}
void WS_Reset(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) //复位
{
GPIO_ResetBits(GPIOx, GPIO_Pin);
WS_delay_us(50);
GPIO_SetBits(GPIOx, GPIO_Pin);
GPIO_ResetBits(GPIOx, GPIO_Pin);
}
/************************************************
* 发送数据
*************************************************/
void WS_Set1(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long dat)
{
unsigned char i;
for(i=0; i<24; i++)
{
if(0x800000 == (dat & 0x800000) )
TX1(GPIOx,GPIO_Pin);
else
TX0(GPIOx,GPIO_Pin);
dat<<=1; //左移一位
}
}
void WS_Set_Date(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned char len,unsigned long dat) // 全部发送同样的数据
{
unsigned char i;
for(i = 0; i <len; i++)
{
WS_Set1(GPIOx,GPIO_Pin,dat);
}
WS_Reset(GPIOx,GPIO_Pin);
}
void WS_SetAll(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) //发送所有字节
{
unsigned char i;
for(i=0;i<nWs;i++)
{
WS_Set1(GPIOx,GPIO_Pin,WsDat_RUN[i]);
}
WS_Reset(GPIOx,GPIO_Pin);
WS_delay_ms(500);
}
/**************************颜色渐变函数***************************/
/*
从起始颜色---最终颜色
*/
unsigned char abs0(int num)//求绝对值
{
if(num>0) return num;
num = -num;
return (unsigned char) num;
}
unsigned long ColorToColor(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color0, unsigned long color1,unsigned int speed)
{
unsigned char Red0, Green0, Blue0; // 起始三原色
unsigned char Red1, Green1, Blue1; // 结果三原色
int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)
unsigned char NStep; // 需要几步
float RedStep, GreenStep, BlueStep; // 各色步进值
unsigned long color; // 结果色
unsigned char i;
// 绿 红 蓝 三原色分解
Red0 = color0>>8;
Green0 = color0>>16;
Blue0 = color0;
Red1 = color1>>8;
Green1 = color1>>16;
Blue1 = color1;
// 绿 红 蓝 三原色分解 若输入的颜色非上述三种
Red0 =( color0&0x00FF00)>>8;
Green0 = (color0&0xFF0000)>>16;
Blue0 = color0;
Red1 = (color1&0x00FF00)>>8;
Green1 = (color1&0xFF0000)>>16;
Blue1 = color1;
// 计算需要多少步(取差值的最大值)
RedMinus = Red1 - Red0;
GreenMinus = Green1 - Green0;
BlueMinus = Blue1 - Blue0;
//判断两个绝对值大小。。a>b为真,则=a;否则=b
NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
// 计算出各色步进值
RedStep = (float)RedMinus / NStep;
GreenStep = (float)GreenMinus / NStep;
BlueStep = (float)BlueMinus / NStep;
// 渐变开始
for(i=0; i<NStep; i++)
{
Red1 = Red0 + (int)(RedStep * i);
Green1 = Green0 + (int)(GreenStep * i);
Blue1 = Blue0 + (int)(BlueStep * i);
color = Green1<<16 | Red1<<8 | Blue1; // 合成 绿红蓝
WS_Set_Date(GPIOx,GPIO_Pin,nWs,color); //发送颜色,所有灯带同色
WS_delay_ms(speed);
}
return color;
}
/*************跑马灯****************
000000000000000000000000
111100000000000000000000
000011110000000000000000
000000001111000000000000
111100000000111100000000
000011110000000011110000
***********************************/
void LED_Init(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color) //初始化显存数组
{
unsigned char i;
for(i=0;i<50;i++)
WsDat_RUN[i]=color;
WS_SetAll(GPIOx,GPIO_Pin);
}
//入口参数 color----speed----temp
// 显示颜色--流水速度--间隔距离
void RUN_LED(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color,unsigned int speed,unsigned char temp)//跑马灯
{
unsigned char i,j;
for(j=0;j<(nWs-1);j++)
{
for(i=nWs;i>0;i--)
WsDat_RUN[i] = WsDat_RUN[i-1];
if(j%temp == 0)
WsDat_RUN[0] = color;
else
WsDat_RUN[0] = Black;
//WS_Set_Date(GPIO_PIN,nWs,WsDat_RUN[i]);
WS_SetAll(GPIOx,GPIO_Pin);
WS_delay_ms(speed);
}
}
main.c
#include "stm32f10x.h"
#include "WS2811.h"
int main()
{
WS_GPIO_Init();//GPIOC和GPIOB初始化
ColorToColor(GPIOB,GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12,Red,Green,10);//颜色渐变端口GPIOB12131415输出
//如果需要其他端口输出先去WS2811.c修改GPIO口初始化函数
}


WS2811模块实物图

此版本在已在正点原子的战舰版本上运行成功,若使用野火、七星虫等其余主流开发板,请参考商家给的硬件连接图进行修改
上一篇:STM32单片机AD4630-24驱动程序
下一篇:【07】STM32备忘_RTC硬件电路设计
推荐阅读最新更新时间:2026-03-19 16:07
- LTC2945IUD-1 在 -48V 系统中使用低侧检测进行电源监控的典型应用
- 用于 24V 汽车应用的 LTC4367IDD 过压电源保护控制器的典型应用
- LTC2635-HZ12 四通道、12 位数模转换器的典型应用
- 使用 ROHM Semiconductor 的 BU4821 的参考设计
- 使用 Analog Devices 的 AD9625 的参考设计
- LT1307CS8 高压反激式转换器的典型应用电路
- AD7858L 3V 至 5V 单电源、200ksps、8 通道、12 位采样 ADC 的典型应用
- AND8337/D、1.2V、1.5V DC 至 DC 单路输出电源参考设计
- DER-713 - 使用 InnoSwitch3-EP PowiGaN 和 MinE-CAP 的 65 W 高功率密度适配器
- LDK120C11R 1.1V低压降稳压器典型应用(可调版)电路

stm32驱动屏IC rm68042
STM32 PMSM FOC 简介
基于STM32G031的测试测量训练平台完成虚拟仪器实现
非常经典的关于LLC的杨波博士论文
1CIS223-04TG3M






京公网安备 11010802033920号