找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11184|回复: 15
收起左侧

DMX512转WS2812面板灯单片机源程序等制作资料下载

  [复制链接]
ID:290266 发表于 2018-4-18 15:47 | 显示全部楼层 |阅读模式
WS2812面板灯制作教程!

视频效果展示:

功能描述
电脑上,使用MADRIX 2.0 软件,读取声卡数据并转换成频谱图像,通过USB口发送给MADRIX板子,转换成DMX512协议,送入面板灯。再由STC8单片机解码,发送给WS2812灯珠,显示出和电脑上一模一样的图像。
同类方案广泛应用于超大型酒吧、室外广场装饰灯等。
所需材料:
1、MADRIX软件(学习可以使用免费版本,如需正规使用请联系官方购买)
2、MADRIX控制器,输出电脑信号转换成DMX512信号即可
3、STC单片机,1KB的RAM,1KB的ROM,最好是带两个串口,宽电压的稳定。
4、MAX490芯片,用于将DMX512协议的485差分信号转换成TTL信号
5、WS2812灯珠
6、电源,输出电压恒压5V,输出电流根据灯珠数量选择。
关于制作:
1、原理图请参考《WS2812面板灯原理图》
2、PCB根据自己需要,选择灯珠的布局形式。标准的DMX512协议最多支持170颗RGB彩灯的灰度数据。
3、STC单片机的程序,请参考《DMX512转WS2812 面板灯程序》
4、WS2812灯珠调试,请参考《全真彩WS2812芯片LED介绍》
关于MADRIX软件的版权
1、软件的下载:见附件
2、软件的授权:学习或者测试,可以直接下载上面的MADRIX软件安装使用。公司使用请务必到MADRIX官网购买正版授权证明。如贵公司侵权使用,所产生法律责任与本文无关!软件在为授权的情况下,只能用于调试,并且会按一定时间自动黑屏!不能用于工业项目的客户使用!
3、安装软件后需要安装驱动才能正常使用MADRIX解码板
4、我们的MADRIX板,只支持MADRIX 2.0版本,升级后将不能正常使用!
MADRIX软件的简单使用
1打开软件,按F4,搜索MADRIX设备出现下列OUT设备,就表示找到设备!
2再按F2,设置面板灯的布局方式,下图是我们的13*13像素点的面板灯的设置
3选择花样
S2LEQUAlizer就是频谱显示,可以调节声音显示幅度、灯珠亮度、显示速度等参数


电路原理图如下:

0.png

级联169颗灯珠,排列成13*13矩阵,总电流7A
适当距离需要增加0.1uF电容作为电源滤波,推荐50颗电容分开放
单颗灯珠电流40毫安,单颗灯珠功耗0.2瓦


单片机源程序如下(主程序):
  1. //***********************************************************************************
  2. //1、程序适用时钟为24M
  3. //2、DMX512的串口2,每48微秒进入一次中断,中断服务里使定时器0重新计时。
  4. //3、接收完513字节后,超过1000微秒保持高电平不进串口中断,定时器溢出使status_flag翻转一次。
  5. //4、如果status_flag是1,那么接下来的DMX512丢弃不用!把DMX接收的数据拷贝并发送给WS2812。
  6. //5、发送完WS2812数据后,再次允许串口2中断,status_flag再翻转一次,保持DMX512数据。
  7. //6、核心目的是留一帧丢一帧,保证DMX512解码和WS2812发送,在时间上错开。
  8. //***********************************************************************************
  9. #include "all.h"
  10. bit status_flag=1;
  11. void Timer0_Init(void)                                                                //1000微秒 24M时钟
  12. {
  13.         AUXR &= 0x7F;                                                                        //定时器工作在12T模式
  14.         TMOD &= 0xF0;                                                                        //设置为定时器模式
  15.         TMOD |= 0x01;                                                                        //设置为定时器模式
  16.         TL0 = 0x30;                                                                                //定时器初值
  17.         TH0 = 0xF8;                                                                                //定时器初值
  18.         TF0 = 0;                                                                                //清除TF0标志
  19.         TR0 = 1;                                                                                //启动定时0
  20.         ET0=1;                                                                                        //允许定时器中断
  21. }
  22. void Timer0_Routnie (void) interrupt 1 using 1
  23. {
  24.         static u8 WS2812_Write_Buffer_old;                                //无信号等待用
  25.         static u16 count;                                                                //无信号等待用
  26.         u16 i;
  27.         
  28.         status_flag=~status_flag;                                                //帧标志位,一次DMX取反一次
  29.         if(status_flag==1)                                                                //如果是奇数,下次DMX512丢弃,而发送WS2812数据
  30.         {
  31.                 WS2812_DAT=0;                                                                //先发送低电平复位时间
  32.                 IE2&=0xfe;                                                                        //关闭DMX的串口2中断
  33.                 for(i=1;i<Pixel_Data_Num;i++)
  34.                 {
  35.                         WS2812_Write_Buffer[i]=DMX512_Read_Buffer[i];//DMX数据复制给WS2812
  36.                 }
  37.                 if(WS2812_Write_Buffer_old!=WS2812_Write_Buffer[1])//如果数据改变
  38.                 {
  39.                         count=0;                                                                //计数从0开始
  40.                         WS2812_Write_Buffer_old=WS2812_Write_Buffer[1];//刷新数据。
  41.                 }
  42.                 else                                                                                //如果数据不改变
  43.                 {
  44.                         count++;                                                                //计时
  45.                         if(count>2417)                                                        //如果长时间数据不改变
  46.                         {
  47.                                 for(i=1;i<Pixel_Data_Num;i++)
  48.                                 {
  49.                                         WS2812_Write_Buffer[i]=0;                //说明通信故障,自动黑屏
  50.                                         DMX512_Read_Buffer[i]=0;                //说明通信故障,自动黑屏
  51.                                 }
  52.                         }
  53.                 }
  54.                 WS2812_Display_Ser();                                                //传输数据到WS2812
  55.                 IE2|=0x01;                                                                        //串口2中断再次允许,下次保存DMX512,不发送WS2812数据
  56.         }
  57. }
  58. void main()
  59. {
  60.         u16 i;
  61.         for(i=0;i<Pixel_Data_Num;i++)
  62.         {
  63.                 WS2812_Write_Buffer[i]=0;                                        //开机先黑屏
  64.                 DMX512_Read_Buffer[i]=0;                                         //开机先黑屏
  65.         }
  66.         DMX_Init();               
  67.         P1M0=0;P3M0=0;
  68.         P1M1=0;P3M1=0;
  69.         WS2812_Init();
  70.         Timer0_Init();
  71.         EA=1;
  72.         while(1);
  73. }
复制代码

DMX512_Drive.c
  1. #include "all.h"
  2. u8 xdata DMX512_Read_Buffer[Pixel_Data_Num];
  3. //**********************************************
  4. //        DMX512初始化串口与定时器 24M
  5. //**********************************************
  6. void DMX_Init()
  7. {
  8.         S2CON = 0xD0;                //9位数据,波特率可设置
  9.         AUXR &= 0xFB;                //定时器2工作在12T模式
  10.         T2L = 0xFE;                        //定时器2初值
  11.         T2H = 0xFF;                        //定时器2初值
  12.         AUXR |= 0x10;                //启动定时器2
  13.         IE2|=0x01;                        //串口2中断允许
  14. }
  15. //**********************************************
  16. //        串口2的中断服务函数  S2RI=1才能进入中断服务
  17. //**********************************************
  18. void Uart2_Routnie (void) interrupt 8 //using 1
  19. {
  20.         static u16 data DMX_count;
  21.         TL0 = 0x30;                                                                        //定时器0重装初值,防止定时器0中断发生
  22.         TH0 = 0xF8;                                                                        //定时器0重装初值,防止定时器0中断发生
  23.         switch(S2CON&0x05)                                                        //判断S2RB8以及S2RI
  24.         {
  25.                 case 1:DMX_count=0;S2CON&=0xf0;break;        //如果S2RB8是0,S2RI是1,清除S2RI
  26.                 case 5:                                                                        //如果S2RB8是1,S2RI是1
  27.                 {
  28.                         if(DMX_count<Pixel_Data_Num)                //只保存需要的最多字节数量
  29.                         {
  30.                                 DMX512_Read_Buffer[DMX_count]=S2BUF;//保存
  31.                         }
  32.                         DMX_count++;                                                //计数器增加
  33.                 }
  34.                 S2CON&=0xf0;                                                        //清除S2RI                                                
  35.                 break;
  36.         }
  37. }
复制代码

WS2812_Drive.c
  1. #include "all.h"
  2. u8 xdata WS2812_Write_Buffer[Pixel_Data_Num];
  3. //**********************************************
  4. //        WS2812初始化
  5. //**********************************************
  6. void WS2812_Init()
  7. {
  8.                 WS2812_DAT=1;                                                        //拉高
  9. }
  10. //**********************************************
  11. //        WS2812 发送数据  0.5625us是高电平的界限。发0高电平不能超过0.5625
  12. //**********************************************
  13. void WS2812_Write_Data(u8 *Point,u8 len)
  14. {        
  15.            u8 data i,j,k,Value;
  16.         for(i=0;i<len;i++)                                                        //多少个RGB灯就发送多少次
  17.         {
  18.                 for(j=0;j<3;j++)                                                //每个灯是R G B 三种颜色数据
  19.                 {
  20.                         switch(j)                                                        //红绿调换位置。
  21.                         {
  22.                                 case 0:Value=*(Point+1);break;
  23.                                 case 1:Value=*(Point);break;
  24.                                 case 2:Value=*(Point+2);break;
  25.                         }
  26.                         for(k=0;k<8;k++)                                        //每个数据是8位
  27.                         {
  28.                                 WS2812_DAT=1;                                          
  29.                                 if(Value&0x80)                                        //判断数据是不是1
  30.                                 {
  31.                                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  32.                                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  33.                                         WS2812_DAT=0;                                 //0.35us
  34.                                         //_nop_();_nop_();
  35.                                 }
  36.                                 else
  37.                                 {        
  38.                                         WS2812_DAT=0;                                 //1.36us
  39.                                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  40.                                         _nop_();_nop_();_nop_();_nop_();_nop_();
  41.                                        
  42.                                                                                     
  43.                                 }
  44.                                 Value<<=1;        
  45.                         }
  46.                 }
  47.                 Point+=3;//指针加加               
  48.         }        
  49. ……………………

  50. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
0.png

所有资料51hei提供下载:
WS2812面板灯制作资料.zip (7.71 MB, 下载次数: 288)
回复

使用道具 举报

ID:166422 发表于 2018-4-21 13:30 | 显示全部楼层
还是有点瑕疵啊,要是能做到不跑帧就完美了。楼主可以试试带DMA的mcu试试
回复

使用道具 举报

ID:340530 发表于 2018-5-29 13:28 | 显示全部楼层
正在找,好用不
回复

使用道具 举报

ID:202754 发表于 2018-8-10 14:42 | 显示全部楼层
正在学习该协议,谢谢
回复

使用道具 举报

ID:3802 发表于 2018-10-15 17:01 | 显示全部楼层
正在找,好用不
回复

使用道具 举报

ID:127971 发表于 2018-12-3 13:39 | 显示全部楼层
正在学习这个协议,资料具有参考价值。
回复

使用道具 举报

ID:414738 发表于 2019-8-22 11:28 | 显示全部楼层
工程很多错误,编译不能通过
回复

使用道具 举报

ID:796897 发表于 2020-7-5 00:26 | 显示全部楼层
谢谢楼主,非常详细的资料
回复

使用道具 举报

ID:706724 发表于 2020-11-2 19:44 | 显示全部楼层
感谢楼主的不辞辛苦的分享
回复

使用道具 举报

ID:240020 发表于 2021-6-3 10:19 | 显示全部楼层
楼主的Madrix控制器是哪里的,我正想自己做一个来玩
回复

使用道具 举报

ID:588322 发表于 2021-7-7 22:05 | 显示全部楼层
很有参考价值,学习了
回复

使用道具 举报

ID:56876 发表于 2021-7-25 16:53 | 显示全部楼层
aolin 发表于 2021-6-3 10:19
楼主的Madrix控制器是哪里的,我正想自己做一个来玩

支持MADRIX软件的控制器我这里有,该控制器支持DMX512和W2812信号的输出。论坛私信我

回复

使用道具 举报

ID:263693 发表于 2021-9-7 12:49 | 显示全部楼层
51的架构好像没有DMA
回复

使用道具 举报

ID:356512 发表于 2023-8-29 01:01 | 显示全部楼层
stc8.h
stc8.rar (2.91 KB, 下载次数: 6)
回复

使用道具 举报

ID:433219 发表于 2023-8-29 20:02 | 显示全部楼层
luokuipeng 发表于 2021-9-7 12:49
51的架构好像没有DMA

都是增强型51后来加的,例如stc8h、stc32g,都有DMA了
回复

使用道具 举报

ID:433219 发表于 2024-5-30 16:14 | 显示全部楼层
界面很现代科幻 Madrix控制器
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表