`
本帖最后由 elecfans跑堂 于 2015-8-28 11:31 编辑
WS2811是一款可以级联的RGB三色LED灯。只需要一根数据线就可以控制多颗LED。现在发上来整理的库函数,可以直接调用显示函数。
WS2811.rar
(1.84 KB)
(下载次数: 1102, 2015-8-26 13:43 上传)
WS2811.h
#ifndef __WS2811_H
#define __WS2811_H
#include "sys.h"
#define White 0xFFFFFF // 白色
#define Black 0x000000 // 黑色
#define Red 0x00ff00 // 红色
#define Green 0xff0000 // 绿色
#define Blue 0x0000ff // 蓝色
#define nWs 16 // 有多少颗WS2811级联
extern unsigned long WsDat[];
extern void WS_Init(void);
extern void WS_SetAll(void);
extern u32 ColorToColor(unsigned long color0, unsigned long color1);
#endif
WS2811.c
/****************************************************************************************
* WS2811 彩灯驱动函数
*
* 调用方法:
* 修改宏定义: #define nWs 1 // 有多少颗WS2811级联
* WS_Init(); // IO初始化
* WsDat[0] = 0x808080;//显存赋值
* WS_SetAll(); // 发送数据
* ColorToColor(unsigned long color0, unsigned long color1);// 颜色渐变算法
*
* 作者:星希望(已校验)
* 日期:2015年6月24日
****************************************************************************************/
#include "sys.h"
#include <
STM32f10x.h>
#include "WS2811.h"
#include "delay.h"
/* 显存 */
unsigned long WsDat[nWs];
/**************************************************************************************
* IO初始化(移植时请修改)
**************************************************************************************/
void WS_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
//端口时钟,使能
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
// 端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PIN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); // 根据设定参数初始化
}
/**************************
* 内部延时
***************************/
void delay2us()
{
unsigned char i;
for(i=0; i<12; i++);
}
void delay05us()
{
unsigned char i;
for(i=0; i<1; i++);
}
/***************************
* 发送一比特
****************************/
void TX0() { PAout(0) = 1; delay05us(); PAout(0) = 0; delay2us(); } // 发送0
void TX1() { PAout(0) = 1; delay2us(); PAout(0) = 0; delay05us(); } // 发送1
void WS_Reset() { PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0; }
/**************************************************************************************
* 发送一字节
**************************************************************************************/
void WS_Set1(unsigned long dat)
{
unsigned char i;
for(i=0; i<24; i++)
{
if(0x800000 == (dat & 0x800000) ) TX1();
else TX0();
dat<<=1; //左移一位
}
}
/**************************************************************************************
* 发送所有字节
**************************************************************************************/
void WS_SetAll()
{
unsigned char j;
for(j=0; j
{
WS_Set1(WsDat[0]); // j / 0
}
WS_Reset();
}
/********************************************
* 求绝对值
********************************************/
unsigned char abs0(int num)
{
if(num>0) return num;
num = -num;
return (unsigned char) num;
}
/***********************************************************************************
* 颜色渐变算法
* 误差 <= 2
************************************************************************************/
u32 ColorToColor(unsigned long color0, unsigned long color1)
{
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;
// 计算需要多少步(取差值的最大值)
RedMinus = Red1 - Red0;
GreenMinus = Green1 - Green0;
BlueMinus = Blue1 - Blue0;
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
{
Red1 = Red0 + (int)(RedStep * i);
Green1 = Green0 + (int)(GreenStep * i);
Blue1 = Blue0 + (int)(BlueStep * i);
color = Green1<<16 | Red1<<8 | Blue1; // 合成 绿红蓝
WsDat[0] = color;
WS_SetAll(); // 输出
delay_ms(1); // 渐变速度
}
// 渐变结束
return color;
}
`