STM32驱动WS2811实现渐变色、跑马灯

发布者:心有归属最新更新时间:2025-11-07 来源: bilibili关键字:STM32  渐变色  跑马灯 手机看文章 扫描二维码
随时随地手机看文章

一、WS2811简介

  1. 输出端口耐压12V

  2. 芯片内置稳压管,24V以下电源端只需串电阻IC到VDD脚,无需外加稳压管

  3. 灰度调节电路(256级灰度可调)

  4. 内置信号整形电路,任何一个IC收到信号后经过波形整形后在输出,保证线路波形畸变不会累加

  5. 内置上电复位和掉电复位电路

  6. PWM控制端能够实现256级调节,扫描频率不低于400HZ/S

  7. 串行接口级联,一根信号线DI完成数据的接收与解码

  8. 任意两点传输距离不超过2米无需增加任何电路

  9. 当刷新速率30帧/秒时,低速模式级联数不小于512点,高速模式下不小于1024点

  10. 数据发送速度可达与400Kbps与800Kbps两种模式

cut-off

二、通讯协议

数据协议采用单线归零码的通讯方式, 像素点在上电复位以后, 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口初始化函数

}

cut-off

WS2811模块实物图

cut-off

此版本在已在正点原子的战舰版本上运行成功,若使用野火、七星虫等其余主流开发板,请参考商家给的硬件连接图进行修改


关键字:STM32  渐变色  跑马灯 引用地址:STM32驱动WS2811实现渐变色、跑马灯

上一篇:STM32单片机AD4630-24驱动程序
下一篇:【07】STM32备忘_RTC硬件电路设计

推荐阅读最新更新时间:2026-03-19 16:07

STM32驱动WS2811实现渐变色跑马灯
一、WS2811简介 输出端口耐压12V 芯片内置稳压管,24V以下电源端只需串电阻IC到VDD脚,无需外加稳压管 灰度调节电路(256级灰度可调) 内置信号整形电路,任何一个IC收到信号后经过波形整形后在输出,保证线路波形畸变不会累加 内置上电复位和掉电复位电路 PWM控制端能够实现256级调节,扫描频率不低于400HZ/S 串行接口级联,一根信号线DI完成数据的接收与解码 任意两点传输距离不超过2米无需增加任何电路 当刷新速率30帧/秒时,低速模式级联数不小于512点,高速模式下不小于1024点 数据发送速度可达与400Kbps与800Kbps两种模式 二、通讯协议 数据协议采用单线归零码的通讯方式,
[单片机]
<font color='red'>STM32</font><font color='red'>驱动</font><font color='red'>WS2811</font>实现<font color='red'>渐变色</font>、<font color='red'>跑马灯</font>
stm32——跑马灯实验(用库函数实现)
库函数介绍 1,初始化函数: void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 作用:初始化一个或者多个IO口(同一组)的工作方式和速度。该函数主要是操作GPIO_CRL(CRH)寄存器,在上拉或者下拉的有时候有设置BSRR或者BRR寄存器 例如: GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef.GPIO_Pin = GPIO_Pin_5;//LED0-- PB.5 端口配置 GPIO_InitTypeDef.GPIO_Mode = GPIO_Mode_OUT_PP;//
[单片机]
<font color='red'>stm32</font>——<font color='red'>跑马灯</font>实验(用库函数实现)
stm32跑马灯——寄存器和位操作
寄存器版: GPIO基础: 每组io口有7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。 硬件连接: 例如: 由上图1可知:要使用到LED0和LED1,他们的IO口分别为PB5和PE5 由上图2可知:要使用到LED0和LED1,他们的IO口分别为PA8和PD2 GPIO的输出模式为推挽输出。 代码: 使能IO口时钟:配置寄存器RCC APB2ENR. 初始化IO口模式:配置寄存器GPIOx CRH/CRL 操作IO口,输出高低电平:配置寄存器GPIOX_ODR或者BSRR/BRR. 这里采用上图1的的原理图: led.h: #ifndef __LED_H //避免重复引用 #d
[单片机]
<font color='red'>stm32</font><font color='red'>跑马灯</font>——寄存器和位操作
STM32 LED跑马灯-库函数
一,GPIO知识回顾 1,四种输入模式: 输入浮空 输入上拉 输入下拉 模拟输入 2,四种输出模式: 开漏输出 开漏复用输出 推挽输出 推挽复用输出 3,三种最大输出速度 2MHz 10MHz 50MHz 每组GPIO共16个IO口,含下7个寄存器 GPIOx_CRL : 端口配置低寄存器 GPIOx_CRH : 端口配置高寄存器 GPIOx_IDR : 端口输入寄存器 GPIOx_ODR : 端口输出寄存器 GPIOx_BSRR : 端口位设置/清除寄存器 GPIOx_BRR : 端口位清除寄存器 GPIOx_LCKR : 端口配置锁存寄存器 二,LED硬件连接
[单片机]
<font color='red'>STM32</font> LED<font color='red'>跑马灯</font>-库函数
基于STM32单片机对跑马灯的控制
基于学习STM32有一段时间了,特意写下一篇关于一个简单的跑马灯 的例程,梳理思路,也希望我自己的理解能帮到一些学习STM32的初学者 //======================================================// 首先,GPIO的配置种类有8种。分别为模拟输入、浮空输入,上拉输入、下拉输入、开漏输出、推挽输出、复用开漏输出、复用推挽输出。 下面将以实例的方式讲解GPIO的设置及实现过程。 事例1:跑马灯实验 跑马灯实验的功能:LED灯进行有规律闪烁。(下面的LED灯的数量都为2个,所以关于寄存器的配置也将以两组的方式进行讲解) 首先要知道普通的IO就两种功能一个为输入,一个为输出
[单片机]
基于<font color='red'>STM32</font>单片机对<font color='red'>跑马灯</font>的控制
STM32日志之总结篇1--跑马灯实验
//======================================================// **基于学习STM32有一段时间了,特意写下一篇关于一个简单的跑马灯 的例程,梳理思路,也希望我自己的理解能帮到一些学习STM32的初学者 //======================================================// 首先,GPIO的配置种类有8种。分别为模拟输入、浮空输入,上拉输入、下拉输入、开漏输出、推挽输出、复用开漏输出、复用推挽输出。 下面将以实例的方式讲解GPIO的设置及实现过程。 事例1:跑马灯实验 跑马灯实验的功能:LED灯进行有规律闪烁。(下面的LED灯的数
[单片机]
红米新机入网,水滴屏 + 渐变色设计
日前红米有一款信号为“M1810F6LE”的新机获得了工信部的入网许可,这款新机型采用了水滴屏 + 渐变色设计,外观造型和红米 Note 7 非常相似,不少人猜测,这或许就是红米 7 。 据悉,这款新机采用的是 6.26 英寸水滴屏,屏幕分辨率为 1520 × 720 ,屏幕比例为 19:9 。而核心配置方面,该机搭载的是八核处理器,CPU 主频为 1.8GHz ,目前尚未清楚具体型号。存储组合方面,该机配备了 2/3/4GB + 16/32/64GB 的存储组合。后置双摄,其中主摄像头为 1200 万像素,前置摄像头则为 800 万像素,电池容量为 4000mAh 。 从配置上看,这款疑似红米 7 的新机定位应该要比红米
[手机便携]
华为nova3i评测:卓越AI四摄/身披蓝紫渐变色
    一、前言:小清新出街潮品 华为nova3i发布 2018年7月18日,华为在深圳发布会上为一直备受年轻人青睐的华为nova系列带来新品,完成了此产品线在今年的更新。 与旗舰机型华为nova3一同亮相的还有华为nova3i——售价1999起步,也可以将其当作华为nova3的青春版本。 nova即新星,有充沛活力、星光闪耀的意象指代,而i则有“自我”之意,两者结合起来充满了青春时代特有的萌萌的又微微“中二”的气息。 意义深远的命名加上华为自研准旗舰移动平台麒麟710的首发搭载,还有GPU Turbo技术的加持,以及AI四摄、高颜值蓝楹紫渐变配色的搭配,都能够让人感觉到华为nova3i所给予年轻人的活力。 快科技现在已经拿到了
[手机便携]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved