文章目录

  • 效果
    • 呼吸
    • 流水
    • 跑马
    • 随机灯带
  • WS2812B 驱动
    • 数据协议
    • 24bit数据结构
  • 程序
    • main.c
    • ws.c
    • ws.h
  • 待做

效果

呼吸

流水

跑马

随机灯带

WS2812B 驱动

数据协议

采用单线归零码,每个像素点(灯),在接受到自己的24bit数据后,将剩下的数据再处理放大后,发出去,也就是每经过一个点,数据少24bit。

RES 帧单位,低电平时间 330us以上
T0L 0码,低电平时间 750ns~1.6us
T0H 0码,高电平时间 220ns~420ns
T1H 1码,高电平时间 750ns~1.6us
T1L 0码,低电平时间 220ns~420ns

注意一点就行了:比例3:1,
比如:
T0L 750ns

T0H 250ns

其对时序要求还是很高的,因此一定要满足要求,不要再数据发的过程中做一些耗时的操作

24bit数据结构

|G7|G6|G5|G4|G3|G2|G1|G0|R7|R6|R5|R4|R3|R2|R1|R0|B7|B6|B5|B4|B3|B2|B1|B0|
高位在前,按照GRB顺序

程序

注意stc15的话,该程序的晶振需设置为24M

main.c

#include <stc15f2k60s2.h>
#include <stdio.h>
#include "ws.h"
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define LEDCNT 50 //灯的数目
sbit k1 = P3^0; //按键一 控制模式
sbit k2 = P3^1;    //按键二 关闭灯光
//成员依次为计时最大值,计时数,是否完成计时
typedef struct delay
{uint max;uint cnt;uchar ok;
} t_delay;
//灯的切换速度(因为定时器是2ms,所以300*2=600ms,以下同理)
t_delay delaytime = {300, 0, 0};
//流水灯的速度(可以设置一个变量然后使用按键控制,都是可以的)
t_delay liushui_time = {30, 0, 0};
//呼吸灯呼吸的速度
t_delay huxi_time = {100, 0, 0};//GRB
//流水灯流完一次改变颜色
code ws_t wsData[] = {{255,0, 0}, {0, 255, 0}, {0, 0, 250}};
//跑马灯的设置
code ws_t PAOMACODE[] = {{255, 0,  0}, {0, 255, 0}, {0, 0, 255}};
unsigned int SEED = 0;//随机数种子//当前按键值,上一次按键值,按键计数
uchar key, tmpKey, keyCnt;
enum
{K_GT,K_AS,K_WA
} keyState = K_GT;enum
{HUXI,LIUSHUI,PAOMA,SUIJI,XIMIE
}gloState = LIUSHUI;//单次获取按键
uchar GetKey()
{if (k1 == 0)return 1;else if(k2 == 0)return 2;return 0;
}
//自我设定定时器运行
void TimeRun(t_delay *time)
{if (time->cnt++ < time->max);else{time->cnt = 0;time->ok = 1;}
}void Timer1Init(void) // 2毫秒@12.000MHz
{AUXR |= 0x40;     //定时器时钟1T模式TMOD &= 0x0F;       //设置定时器模式TL1 = 0x80;       //设置定时初值TH1 = 0x44;        //设置定时初值TF1 = 0;       //清除TF1标志TR1 = 1;      //定时器1开始计时ET1 = 1;
}
//为了调试用的
void UartInit(void)
{SCON = 0x50;AUXR |= 0x01;AUXR |= 0x04;T2L = 0xE0;T2H = 0xFE;AUXR |= 0x10;ES = 0;}
void Timer1Handle() interrupt 3
{switch (keyState){case K_GT:tmpKey = GetKey();keyState = K_AS;keyCnt = 0;break;case K_AS:if (keyCnt++ < 10);else if (tmpKey == GetKey()){if (tmpKey != key){key = tmpKey;keyState = K_WA;}elsekeyState = K_GT;}elsekeyState = K_GT;break;}//在定时器中计算一个定时TimeRun(&delaytime);TimeRun(&liushui_time);TimeRun(&huxi_time);
}void Liushui()
{static uchar i = 0;static uchar color = 0;if(liushui_time.ok == 1){liushui_time.ok = 0;SendLiushui(LEDCNT, i, wsData[color]);i = (i + 1)%LEDCNT;if(i == 0){color = (color + 1)%3;}}
}
void Paoma()
{static uchar i = 0;if(delaytime.ok == 1){delaytime.ok = 0;SendPaoma(LEDCNT, PAOMACODE[i]);i = (i + 1)%3;}
}
void Suiji()
{if(delaytime.ok == 1){delaytime.ok = 0;SendSuiji(LEDCNT);}
}
void Huxi()
{static uchar i = 0;if(huxi_time.ok == 1){huxi_time.ok = 0;SendHuxi(LEDCNT, i);i = (i + 1)%30;}
}void main()
{Timer1Init();UartInit();EA = 1;while (1){switch(gloState){case LIUSHUI:Liushui();break;case PAOMA:Paoma();break;case SUIJI:Suiji();break;case HUXI:Huxi();break;} if(keyState == K_WA){if(key == 1){if(gloState == XIMIE){gloState = HUXI;}else{gloState = (gloState + 1)%4;}}else if(key == 2)//如果按键二按下,则熄灭全部灯{SendXime(LEDCNT);gloState = XIMIE;}keyState = K_GT;}}
}

ws.c

#include <STC15F2K60S2.H>
#include <INTRINS.H>
#include <stdio.h>
#include <stdlib.h>
#include "ws.h"sbit LED = P2^4; //灯带的数据输入
//呼吸灯的值(这部分可以写一个RGB2HSV转换,这里我直接查找的值)
code ws_t HUXICODE[] = {{32,11,227}, {29,10,201},{23,7,165}, {21,7,143}, {17,5,122},{15,5,101},{12,4,81}, {6,2,43}, {3,1,18}, {0,0,0},{31,219,4}, {27,188,3},{23,167,3}, {21,146,3}, {18,125,2},{15,104,2},{12,84,1}, {7,52,1}, {5,33,1}, {0,0,0},{218,100,3}, {188,86,3},{167,77,3}, {149,68,2}, {125,57,2},{104,48,2},{84,38,1}, {63,29,1}, {26,12,0}, {0,0,0}};//每一帧至少的间隙
void Delay300us()       //@24.000MHz
{unsigned char i, j;i = 1;j = 146;do{while (--j);} while (--i);
}
//发送24个bit数据
void WS_SendData(ws_t *_data)
{uchar i = 0;uchar j = 0;uchar *p = (uchar*)_data;EA = 0;for (i = 0; i < 3; i++){uchar tmpData;tmpData = *(p++);for (j = 0; j < 8; j++){if (((tmpData>>(7-j)) & 0x01) == 0){LED = 1;_nop_();_nop_();_nop_();    LED = 0;_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();      }else{LED = 1;_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();        LED = 0;_nop_();_nop_();_nop_();    }}}EA = 1;
}//流水灯
//总个数,哪一个灯亮,亮什么值
void SendLiushui(uchar num,uchar whichLight, ws_t _data)
{uint i = 0;ws_t ximieValue = {0, 0, 0};for(i = 0; i< num+1; i++){//到该亮的地方才亮if((i >= whichLight) && (i <= whichLight + 5)){WS_SendData(&_data);   }else{WS_SendData(&ximieValue); }}Delay300us();
}
//熄灭所有灯
void SendXime(uchar num)
{uint i = 0;ws_t ximieValue = {0, 0, 0};for(i = 0; i< num+1; i++){WS_SendData(&ximieValue);    }LED = 0;Delay300us();
}
//跑马灯
void SendPaoma(uchar num, ws_t _data)
{static uchar start = 0;uint i = 0;ws_t ximieValue = {0, 0, 0};for(i = 0; i< num+1; i++){//一半亮一半不亮if((i%2) == start){WS_SendData(&_data);   }else{WS_SendData(&ximieValue); }}start = (start + 1)%2;Delay300us();
}
void SendSuiji(uchar num)
{uint i = 0;for(i = 0; i< num+1; i++){//随机颜色ws_t suijiValue = {0,0,0};suijiValue.green = SEED>>8;suijiValue.red = SEED;suijiValue.blue = ~SEED;SEED = SEED + 455;WS_SendData(&suijiValue);  }Delay300us();
}
//根据已经设定的值来亮
void SendHuxi(uchar num, uchar lightLevel)
{uint i = 0;for(i = 0; i< num+1; i++){WS_SendData(&HUXICODE[lightLevel]);   }Delay300us();
}

ws.h

#ifndef _WS_H
#define _WS_H#define uchar unsigned char
#define uint unsigned intextern unsigned int SEED;//随机种子
typedef struct ws
{uchar green;uchar red;uchar blue;
}ws_t;void WS_SendData(ws_t* _data);
void SendLiushui(uchar num,uchar whichLight, ws_t _data);
void SendXime(uchar num);
void SendPaoma(uchar num, ws_t _data);
unsigned int random(unsigned int xxx);
void SendSuiji(uchar num);
void SendHuxi(uchar num, uchar lightLevel);
#endif

待做

RGB2HSV


ws2812B+单片机驱动相关推荐

  1. 单片机驱动DM9000网卡芯片(详细调试过程)【下】

    http://hi.baidu.com/mcu8031/blog/item/c95903138671c625dc540171.html 单片机驱动DM9000网卡芯片(详细调试过程)[下] 4.验证初 ...

  2. 单片机led闪烁代码_单片机驱动LED发光二极管的电路以及编程

    一.单片机驱动单个发光二极管 1.电路 代码: 1.点亮单个LED二极管 #include<reg51.h> sbit LED1=P1^0:void main(void){LED1=1:w ...

  3. Linux驱动(3)--单片机驱动与Linux驱动的区别

    单片机驱动与Linux驱动的区别 1. MCU与MPU的区别 2. 单片机驱动与Linux驱动的区别 1. MCU与MPU的区别 首先我们先聊一下MCU与MPU之间的区别然后在去关心两者的驱动的不同. ...

  4. 控制led闪烁次数_单片机驱动LED灯的进阶之路

    对于大多数单片机的学习者或者是从事单片机行业的工程师来说,单片机驱动LED闪烁起来的时候,基本都是我们入坑的开始,同时当时的那种兴奋与喜悦都是难以忘怀的,从LED灯亮起,到闪烁,再到各种流水灯,能开心 ...

  5. K_A08_004 基于 STM32等单片机驱动MX1919模块按键控制直流电机正反转加减速启停

    目录 一.资源说明 二.基本参数 1.参数 2.引脚说明 三.驱动说明 1.MX1919模块驱动时序 2.对应程序: 3.PWM信号 四.部分代码说明 接线说明 1.STC89C52RC+MX1919 ...

  6. 【经验分享】调试STM32F107VC单片机驱动DP83848以太网PHY芯片时遇到的问题

    调试时使用的程序:https://blog.csdn.net/ZLK1214/article/details/105457370 [杜邦线(或普通电线)影响时钟信号的完整性] 笔者调试STM32F10 ...

  7. 【解决方案】STM32L152单片机驱动段码LCD屏,执行HAL_LCD_Init函数失败返回HAL_TIMEOUT,长时间卡在LCD_FLAG_RDY的while循环里面的解决办法

    STM32L152单片机驱动段码LCD屏,HAL_LCD_Init函数执行失败,卡在LCD_FLAG_RDY里面,函数返回HAL_TIMEOUT /*!< Wait Until the LCD ...

  8. 按键控制c51单片机驱动unl2003控制步进电机正反转停止及程序调速-萌新入门

    ** 按键控制c51单片机驱动unl2003控制步进电机正反转停止及程序调速 ** 分享一个萌新入门小工程 一.原件连接: 第一种直接用51开发板 第二种用最小单元加unl2003驱动 二.开发板电路 ...

  9. 液晶显示屏的C语言编码,AT89C51单片机驱动液晶显示汉字C语言

    此程序的完整工程文件下载:http://www.51hei.com/f/8952lkj_c.rar  上图是原理图及其仿真效果. /********************************** ...

  10. 单片机驱动LM75采集温度

    多种型号单片机驱动LM75采集温度 LM75简介 引脚说明 寄存器说明 测试程序 arduino程序 89c51程序 STM32程序 原文链接:https://www.yourcee.com/news ...

最新文章

  1. 第五个页面:更多电影页面
  2. 关于Latex一个简单例子
  3. 研发流程与项目管理之关系
  4. 真的,太多人辜负了.NET5!
  5. mysql2008优化_SQL server 2008 数据库优化常用脚本
  6. bzoj 1488: [HNOI2009]图的同构
  7. excel VBA编程入门,自定义excel数据库模板生成sql语句
  8. 安装 LaserJet 1020 时这个设备的驱动程序丢失了一个必需的项,这可能是由于 inf 是为 Windows 95 或更新版本而写的。联系您的硬件供应商。
  9. 3dmax导出unity3d模型设置
  10. 使用费马小定理和欧拉定理计算余数
  11. 万字长文看看.NET的前世今生与将来
  12. UVALive 7456 Least Crucial Node
  13. 家里的电脑通过电信宽带设置成外网服务器
  14. 【网络安全】重放攻击(Replay Attacks)
  15. 2014Esri中国用户大会亮点系列之——典型案例与应用阐释新一代WebGIS
  16. PMP续证流程全解析
  17. 用c语言破解数控机床plc密码,各种机床系统密码大全,赶紧收藏 以备急用
  18. Sumo 搭建交叉路口交通流仿真平台
  19. 关于贝加莱Modbus通讯的总结
  20. ubuntu下使用360wifi2

热门文章

  1. java我行我素购物系统_用java怎么编写 我行我素shopping购物管理体统
  2. Python3实现百度云盘资源自动转存
  3. 花呗问答匹配(part3 各种模型运行)
  4. 信号硬件入门--振幅调制信号发生器(正弦波发生器方案、AM调制方案)--First理论部分
  5. LoadRunner压力测试:详细操作流程
  6. vscode有趣插件
  7. JEB动态调试debug模式
  8. 第一行代码 第二版pdf及源码(分享)
  9. wifi频率和zigbee干扰_怎样设置Zigbee和wifi信道避免干扰?
  10. java5 64_java8 64位(官方免费版下载2020)