• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【原创】高山云教你之四----利用51单片机实现DMX512协议控制LED灯

利用51单片机实现DMX512协议控制LED灯

DMX512协议
1.协议简介
DMX是Digital MultipleX的缩写 ,意为多路数字传输。DMX512 控制协议是美国舞台灯光协会(USITT)于1990年发布的灯光控制器与灯具设备进行数据传输的工业标准 ,全称是 USITT DMX512(1990) ,包括电气特性、 数据协议、 数据格式等方面的内容。
2.电气特性和物理层
2.1.电气特性
DMX512采用EIA-485标准。
发送端:逻辑“1”以两线间压差+(2~6)V表示;
逻辑“0”以两线间压差为-(2~6)V表示;
接收端:A比B高200mv以上即认为是逻辑“1”;
		  A比B低200mv以上即认为是逻辑“0”。

2.2.拓扑结构
如图1所示为EIA-485电路拓扑结构,一条EIA-485数据链路包括一个差分线驱动设备(D)和多个差分接收终端(R)。

图1基于485的 DMX512拓扑结构
2.3.DMX512 端口及数据链路 因为是采用485差分信号传输,因此DMX512端口一般采用3针或5针接口,相对应的导线则为1对或2对双绞线,导线同时应采用箔片或编织筛包裹。XLR针口分配如下表1所示,其中辅助数据链路可以不用。

基于EIA-485传输距离理论上可以达到1200m,建议控制在800m以内,若要加长传输距离,则需考虑中继器。DMX512数据链路的终接方式应消除信号环路和信号反射,否则可能导致正确设计的系统出现误操作。采用结终端电阻的方式可以消除信号反射,DMX512标准要求,终端电阻应放置在数据+和数据-信号针之间,阻抗范围120Ω+5%~120Ω-10%。 3.数据协议格式及传输 DMX512 协议规定数据以数据包的形式通过异步通讯的方式进行传输。每个数据包由若干数据帧组成, 每帧数据包括1 位低电平起始位、8 位数据位和2 位高电平停止位。DMX512协议要求数据传输的波特率为250kbps, 亦即每位的传输时间为4us, 每帧数据的传输时间为44us, 它支持多达512 帧数据传输, 每帧数据与相应的控制支路相对应。数据包的传送要符合一定的格式和时序要求,每个包需要发送2~513个字节数据(由总线设备来确定)。为了使接收器能够分辨出第一帧数据, 每一个数据包以一个不短于88us 的低电平信号为起始信号, 即所谓的BREAK信号, 接收器接收到BREAK信号就准备接受随后而来的数据帧; 紧接着BREAK信号之后是不短于8us 的高电平信号MAB (Mark after Break) ; 之后就是数据帧。在DMX512协议中, MAB之后的第一帧数据被称为SC(Start code), 即起始字节,在协议中规定其为零, 但在实际应用中可以由生产厂家自己确定其具体的值, 以传递特殊消息。SC标明其后面的数据是8位控制信号数据帧。一个数据包发送完成后,可以发送MT BP。MT BP (Mark Time Between Packets)标志着一个完整的信息包发送完毕 ,是下一个信息包即将开始的 “空闲位”,高电平有效数据帧之间可以有时间间隔, 也可以没有; 同样, 数据包之间可以有时间间隔, 也可以没有。DMX512协议规定BREAK信号、MAB信号的最短时间, 并规定BREAK信号、MAB信号、数据帧之间及数据包之间的时间间隔的最大值不得超过1s, 否则做出错处理, 但是DMX512 协议并未对出错处理做任何规定。DMX512协议所规定的数据格式如图2所示,各信号的定时时间如表2所示

图2中,虚线框内为一个数据帧的格式,S为1个比特起始位(低电平),E为2比特的停止位(高电平),D0~D7为8个比特的控制数据,其电平组合从 00000000~11111111 共有 256 个状态(对应十进制数的0~255) ,控制灯光的亮度时 ,可产生256个亮度等级 ,00000000 (0)对应灯光最暗 ,11111111(255)对应灯光最亮。信息包中,第1帧对应第1回路的灯具,第2帧对应第2回路灯具,依此类推,第512帧对应第512回路灯具,灯具回路的地址在灯具上可设置。 DMX512协议是一种基于主从式的协议,能够适应一对多的灯光控制系统。

全部回复(31)
正序查看
倒序查看
2014-06-25 15:32
DMX512这个好像就是基于RS485通信协议的一种方式吧,这种方式只能一点对多点,不过用来控制灯光也完全够了,因为灯光是不用反馈数据的。
0
回复
2014-06-25 15:46
乐工回来啦,新帖果断支持!~
0
回复
2014-06-25 15:52
@电源网-娜娜姐
乐工回来啦,新帖果断支持!~
哈哈,回来了,也忙完了,感谢师长!
0
回复
2014-06-25 15:52

原理图如下:

0
回复
2014-06-26 09:13
//============================================================================
//================         DMX512接收数据=====================================
//============================================================================   

#include
#define uchar unsigned char
#define uint  unsigned int

#define ON  1
#define OFF 0

sbit         R = P1^7 ;
sbit         G = P1^6 ;
sbit         Y = P1^5 ;

sbit   COM   =  P3^7 ;

sbit   EN_485   = P3^4;                        
sbit   Work_LED = P3^3;                         
sbit   TXD      = P3^1;                         

uint   Address;                     //  Set_R, Set_G, Set_B  ;  //3路 接收和设置地址
bit    start_ok, Head_ok;
bit    DMX512_ok;                 //DMX512信号标志
uchar  cnt;                                                      //

uchar  R_dat,  G_dat,  B_dat ;     //RGB三路数据
uint   DMX_channel;                //DMX三路的起始地址
uchar  PWM;

/******************************************************************
- 功能描述:延时函数
- 隶属模块:无
- 函数属性:无
- 参数说明:无         
- 返回说明:无
- 注:.....
******************************************************************/
void Delay(uint ms)
{ uint a,b;
        for(a=ms;a!=0;a--)
            for(b=1210;b!=0;b--)
                   ;
    WDT_CONTR= 0x3d; 
}

/******************************************************************
- 功能描述:PWM扫描
- 隶属模块:无
- 函数属性:无
- 参数说明:无         
- 返回说明:无
- 注:.....
******************************************************************/
void RGB(void)
{ 
	uchar x;
	for(x=255;x!=0;x--)
	for(PWM=0;PWM!=255;PWM++)  
	{
		if(R_dat>PWM) 
			{R=ON;}
		else                  
			{R=OFF;} 
			       
		if(G_dat>PWM) 
			{G=ON;}
		else                
			{G=OFF;}
		
		if(B_dat>PWM) 
			{Y=ON;}
		else                  
			{Y=OFF;}
	}                  
}

/******************************************************************
- 功能描述:七彩跳变函数
- 隶属模块:无
- 函数属性:无
- 参数说明:无         
- 返回说明:无
- 注:.....
******************************************************************/
void Tianbian(void)
{ uchar x=1,y;
   do
   {
                switch(x)
                {
                case 1:        
                   R=ON; G=Y=OFF; Delay(5);  break;
                case 2: 
                   G=ON; R=Y=OFF; Delay(5);  break;
                case 3:
                   Y=ON; G=R=OFF; Delay(5);  break;
                case 4:
                   R=OFF; G=Y=ON; Delay(5);  break;
                case 5: 
                   G=OFF; R=Y=ON; Delay(5);  break;
                case 6:  
                   Y=OFF; G=R=ON; Delay(5);  break;
                case 7:   
                   Y=ON; G=R=ON;  Delay(5);  break;        

                default:  x=1;                        break;

                }                                                         
                if(y++>100) 
                  {y=0;x++;}

   }while(!DMX512_ok);
}

/******************************************************************
- 功能描述:主函数
- 隶属模块:无
- 函数属性:无
- 参数说明:无         
- 返回说明:无
- 注:.....
******************************************************************/
void main(void)
{
     SCON=0xD0;             //UART工作于方式3  波特率为(1+SMOD)·(定时器1的溢出率)/32  REN=1接收允许
     PCON=0x0;              //不倍频,晶振24M 
     AUXR|=0X40;            //T1工作在1T模式*12         
     TMOD=0x20;             //T1工作于8位自动重装模式
     TH1 =0xFD;             //波特率20833*12=250K
     TL1 =0xFD;        

     TR1=1;                      //开定时器1
     PS=1;                  //设置串口中断为最高优先级
     ES=1;                  //开UART中断         
     EA=1;                                        //开总中断

     WDT_CONTR= 0x3d;             //开看门狗         64分频  16M   0.67s 

     cnt=3;                        //3通道
  
     EN_485=0;                        //MAX485收发选择 EN_485=1发, EN_485=0收
	/**************************************************************/	
     P1M1=0X00;                    //P1口设为推挽输出
     P1M0=0XFF;
     P3M1=0X00;                    //P3口设为推挽输出        P3.7为普通IO
     P3M0=0XFE;
	/**************************************************************/	    
	COM=0; 
	P1=0;
	Work_LED=0;	
	R=G=Y=OFF;
	Delay(10);

while(1)
  {        
	DMX512_ok=0;	   //DMX512信号标志
	DMX_channel=0;	   //DMX三路的起始地址
	WDT_CONTR= 0x3d;
	RGB();
	if(!DMX512_ok)
	{
		Tianbian();  //无信号
	}
  }
}

/******************************************************************
- 功能描述:串口中断函数,实现DMX512数据接收
- 隶属模块:无
- 函数属性:无
- 参数说明:无         
- 返回说明:无
- 注:.....
******************************************************************/
void Rec(void) interrupt 4             
{ 
	if(RI==1)  
	{ 
		RI=0; 
		if(Head_ok)                            //收到头码就可以收数据码
		{
			DMX512_ok=1;
			if( Address == DMX_channel )       //R 地址比较            
			{ 
				R_dat = SBUF;                   //取出数据 
				cnt--;
				if(!cnt) 
				{ 
					Address = 0; 
					start_ok = 0; 
					cnt=3; 
					Head_ok=0;   
				}
			} 
	      /**************************************************************/		 
			if(Address == DMX_channel+1 )      //G 地址比较                        
			{ 
				G_dat = SBUF;                  //取出数据 
				cnt--;
				if(!cnt) 
				{ 
					Address = 0; 
					start_ok = 0; 
					cnt=3; 
					Head_ok=0;   
				}
			}
		 /**************************************************************/	
			if( Address == DMX_channel+2 )      //G 地址比较                        
			{ 
				B_dat = SBUF;                    //取出数据 
				cnt--;
				if(!cnt) 
				{ 
					Address = 0; 
					start_ok = 0; 
					cnt=3; 
					Head_ok=0;  
				}
			}
		  /**************************************************************/	
			if(++Address>=512)                 //  地址溢出                
			{                 
				Address = 0; start_ok = 0; cnt=3; Head_ok=0;          //到此512个比较完
			}                             
		}  
		else
		{                      
			if(!RB8)//             //判断收到的第九位数据,只有在DMX送出>88us低电平的中断信号时(也叫同步码,起始码,),RB8才会为0
			{ 
				start_ok=1;   //收到起始位
				Address=0;    //0-255共256个通道                       
			}
			 
			else if(start_ok)
			{
				Head_ok=1;    // 收到设备信息数据
			}
		}
	} 
} 
 
0
回复
2014-06-26 14:16
@yueyunno1
//============================================================================//================DMX512接收数据=====================================//============================================================================#include#defineucharunsignedchar#defineuintunsignedint#defineON1#defineOFF0sbitR=P1^7;sbitG=P1^6;sbitY=P1^5;sbitCOM=P3^7;sbitEN_485=P3^4;sbitWork_LED=P3^3;sbitTXD=P3^1;uintAddress;//Set_R,Set_G,Set_B;//3路接收和设置地址bitstart_ok,Head_ok;bitDMX512_ok;//DMX512信号标志ucharcnt;//ucharR_dat,G_dat,B_dat;//RGB三路数据uintDMX_channel;//DMX三路的起始地址ucharPWM;/******************************************************************-功能描述:延时函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidDelay(uintms){uinta,b;for(a=ms;a!=0;a--)for(b=1210;b!=0;b--);WDT_CONTR=0x3d;}/******************************************************************-功能描述:PWM扫描-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidRGB(void){ucharx;for(x=255;x!=0;x--)for(PWM=0;PWM!=255;PWM++){if(R_dat>PWM){R=ON;}else{R=OFF;}if(G_dat>PWM){G=ON;}else{G=OFF;}if(B_dat>PWM){Y=ON;}else{Y=OFF;}}}/******************************************************************-功能描述:七彩跳变函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidTianbian(void){ucharx=1,y;do{switch(x){case1:R=ON;G=Y=OFF;Delay(5);break;case2:G=ON;R=Y=OFF;Delay(5);break;case3:Y=ON;G=R=OFF;Delay(5);break;case4:R=OFF;G=Y=ON;Delay(5);break;case5:G=OFF;R=Y=ON;Delay(5);break;case6:Y=OFF;G=R=ON;Delay(5);break;case7:Y=ON;G=R=ON;Delay(5);break;default:x=1;break;}if(y++>100){y=0;x++;}}while(!DMX512_ok);}/******************************************************************-功能描述:主函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidmain(void){SCON=0xD0;//UART工作于方式3波特率为(1+SMOD)·(定时器1的溢出率)/32REN=1接收允许PCON=0x0;//不倍频,晶振24MAUXR|=0X40;//T1工作在1T模式*12TMOD=0x20;//T1工作于8位自动重装模式TH1=0xFD;//波特率20833*12=250KTL1=0xFD;TR1=1;//开定时器1PS=1;//设置串口中断为最高优先级ES=1;//开UART中断EA=1;//开总中断WDT_CONTR=0x3d;//开看门狗64分频16M0.67scnt=3;//3通道EN_485=0;//MAX485收发选择EN_485=1发,EN_485=0收/**************************************************************/P1M1=0X00;//P1口设为推挽输出P1M0=0XFF;P3M1=0X00;//P3口设为推挽输出P3.7为普通IOP3M0=0XFE;/**************************************************************/COM=0;P1=0;Work_LED=0;R=G=Y=OFF;Delay(10);while(1){DMX512_ok=0;//DMX512信号标志DMX_channel=0;//DMX三路的起始地址WDT_CONTR=0x3d;RGB();if(!DMX512_ok){Tianbian();//无信号}}}/******************************************************************-功能描述:串口中断函数,实现DMX512数据接收-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidRec(void)interrupt4{if(RI==1){RI=0;if(Head_ok)//收到头码就可以收数据码{DMX512_ok=1;if(Address==DMX_channel)//R地址比较{R_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(Address==DMX_channel+1)//G地址比较{G_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(Address==DMX_channel+2)//G地址比较{B_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(++Address>=512)//地址溢出{Address=0;start_ok=0;cnt=3;Head_ok=0;//到此512个比较完}}else{if(!RB8)////判断收到的第九位数据,只有在DMX送出>88us低电平的中断信号时(也叫同步码,起始码,),RB8才会为0{start_ok=1;//收到起始位Address=0;//0-255共256个通道}elseif(start_ok){Head_ok=1;//收到设备信息数据}}}}
此贴已被推荐到论坛首页置顶头条~乐工继续!
0
回复
2014-06-26 14:39
@电源网-娜娜姐
此贴已被推荐到论坛首页置顶头条~乐工继续!
前段时间在帖子上看到有人在谈论用单片机来做DMX512协议去控制LED灯,这几天刚好有点时间就写了个,有部分资料也来自网上
0
回复
电子梦
LV.2
9
2014-06-26 14:44
@yueyunno1
前段时间在帖子上看到有人在谈论用单片机来做DMX512协议去控制LED灯,这几天刚好有点时间就写了个,有部分资料也来自网上
正打算做DMX512的灯具,及时雨呀,网上也有很多资料,但是程序写得清晰明了的基本是没有的。
0
回复
2014-06-26 15:00
@电子梦
正打算做DMX512的灯具,及时雨呀,网上也有很多资料,但是程序写得清晰明了的基本是没有的。
撸主你这个程序应该就是一个标准的DMX512程序吧,但是还有个问题,不带地址设置呀,如果有20条灯连接在一起的话估计全部都是一种变化效果,20条灯会同时动作。
0
回复
a2895812
LV.2
11
2014-06-26 15:08
@电子梦
正打算做DMX512的灯具,及时雨呀,网上也有很多资料,但是程序写得清晰明了的基本是没有的。
标记个,下班回去了我也找段DMX512协议的调光灯程序贴上来,很久以前写的,非常乱,但是可以用。可以在普通ATMEL的2051上使用。方式和楼主不太一样,楼主的是中断接收,我的是查询接收;楼主的是主循环产生PWM,我的是定时器产生PWM。
0
回复
li9983456
LV.1
12
2014-06-28 08:34
@a2895812
标记个,下班回去了我也找段DMX512协议的调光灯程序贴上来,很久以前写的,非常乱,但是可以用。可以在普通ATMEL的2051上使用。方式和楼主不太一样,楼主的是中断接收,我的是查询接收;楼主的是主循环产生PWM,我的是定时器产生PWM。
哇!这里还有有个高山云的新帖子,得顶~
0
回复
xiao245896
LV.1
13
2014-06-28 08:37
@li9983456
哇!这里还有有个高山云的新帖子,得顶~
恩,就是得支持,感谢楼主分享这么多。
0
回复
phantasm
LV.5
14
2014-07-01 22:17
@yueyunno1
//============================================================================//================DMX512接收数据=====================================//============================================================================#include#defineucharunsignedchar#defineuintunsignedint#defineON1#defineOFF0sbitR=P1^7;sbitG=P1^6;sbitY=P1^5;sbitCOM=P3^7;sbitEN_485=P3^4;sbitWork_LED=P3^3;sbitTXD=P3^1;uintAddress;//Set_R,Set_G,Set_B;//3路接收和设置地址bitstart_ok,Head_ok;bitDMX512_ok;//DMX512信号标志ucharcnt;//ucharR_dat,G_dat,B_dat;//RGB三路数据uintDMX_channel;//DMX三路的起始地址ucharPWM;/******************************************************************-功能描述:延时函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidDelay(uintms){uinta,b;for(a=ms;a!=0;a--)for(b=1210;b!=0;b--);WDT_CONTR=0x3d;}/******************************************************************-功能描述:PWM扫描-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidRGB(void){ucharx;for(x=255;x!=0;x--)for(PWM=0;PWM!=255;PWM++){if(R_dat>PWM){R=ON;}else{R=OFF;}if(G_dat>PWM){G=ON;}else{G=OFF;}if(B_dat>PWM){Y=ON;}else{Y=OFF;}}}/******************************************************************-功能描述:七彩跳变函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidTianbian(void){ucharx=1,y;do{switch(x){case1:R=ON;G=Y=OFF;Delay(5);break;case2:G=ON;R=Y=OFF;Delay(5);break;case3:Y=ON;G=R=OFF;Delay(5);break;case4:R=OFF;G=Y=ON;Delay(5);break;case5:G=OFF;R=Y=ON;Delay(5);break;case6:Y=OFF;G=R=ON;Delay(5);break;case7:Y=ON;G=R=ON;Delay(5);break;default:x=1;break;}if(y++>100){y=0;x++;}}while(!DMX512_ok);}/******************************************************************-功能描述:主函数-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidmain(void){SCON=0xD0;//UART工作于方式3波特率为(1+SMOD)·(定时器1的溢出率)/32REN=1接收允许PCON=0x0;//不倍频,晶振24MAUXR|=0X40;//T1工作在1T模式*12TMOD=0x20;//T1工作于8位自动重装模式TH1=0xFD;//波特率20833*12=250KTL1=0xFD;TR1=1;//开定时器1PS=1;//设置串口中断为最高优先级ES=1;//开UART中断EA=1;//开总中断WDT_CONTR=0x3d;//开看门狗64分频16M0.67scnt=3;//3通道EN_485=0;//MAX485收发选择EN_485=1发,EN_485=0收/**************************************************************/P1M1=0X00;//P1口设为推挽输出P1M0=0XFF;P3M1=0X00;//P3口设为推挽输出P3.7为普通IOP3M0=0XFE;/**************************************************************/COM=0;P1=0;Work_LED=0;R=G=Y=OFF;Delay(10);while(1){DMX512_ok=0;//DMX512信号标志DMX_channel=0;//DMX三路的起始地址WDT_CONTR=0x3d;RGB();if(!DMX512_ok){Tianbian();//无信号}}}/******************************************************************-功能描述:串口中断函数,实现DMX512数据接收-隶属模块:无-函数属性:无-参数说明:无-返回说明:无-注:.....******************************************************************/voidRec(void)interrupt4{if(RI==1){RI=0;if(Head_ok)//收到头码就可以收数据码{DMX512_ok=1;if(Address==DMX_channel)//R地址比较{R_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(Address==DMX_channel+1)//G地址比较{G_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(Address==DMX_channel+2)//G地址比较{B_dat=SBUF;//取出数据cnt--;if(!cnt){Address=0;start_ok=0;cnt=3;Head_ok=0;}}/**************************************************************/if(++Address>=512)//地址溢出{Address=0;start_ok=0;cnt=3;Head_ok=0;//到此512个比较完}}else{if(!RB8)////判断收到的第九位数据,只有在DMX送出>88us低电平的中断信号时(也叫同步码,起始码,),RB8才会为0{start_ok=1;//收到起始位Address=0;//0-255共256个通道}elseif(start_ok){Head_ok=1;//收到设备信息数据}}}}
了解一下 虽然都用不用
0
回复
2014-07-02 10:13
@phantasm
了解一下虽然都用不用
此贴已经被推荐社区经典!大家继续~楼主加油!~
0
回复
a2895812
LV.2
16
2014-07-02 21:24
@a2895812
标记个,下班回去了我也找段DMX512协议的调光灯程序贴上来,很久以前写的,非常乱,但是可以用。可以在普通ATMEL的2051上使用。方式和楼主不太一样,楼主的是中断接收,我的是查询接收;楼主的是主循环产生PWM,我的是定时器产生PWM。

//**********************************************************

//stc 2051 兼容ATMEL2051

//16M晶振 250k波特率

//最简实验DMX512调光序

//**********************************************************

//P3_5 - P1 0-511 通道选择 自动更新

//P3_2 P3_3 P3_4 R G B输出。

//**********************************************************  

 #include   

 #define        uchar unsigned char

//**********************************************************

//定义全局变量给中断程序使用。

//********************************************************** 

  uchar t0_mark=0x00,  data1=0x00, data2=0x00, data3=0x00,data4=0x00,

data5, data6, data7;  

 uchar da1=0x80, da2=0x80, da3=0x80,da4=0xff,mark=0x00,add=0x00; 

  unsigned  int   time;

//*******************************************************

//协议程序 

//*******************************************************  

 void start_bit(void) 

  { uchar a;     TR0=1;        while (P3_0==1);  

 // 等待传输暂停

 TR0=0;

TH0=0x00;

TL0=0x00;

TR0=1;

while  (P3_0==0); //等待端口变化

if(TL0>0x80||TH0>0x00)  //大于96微秒 

  { REN=1;time=0x00;while(RI==0);    

  data1=SBUF;  

if (mark==0x00)   

  { for( a=add; a!=0x00; a--){while(RI==0);   RI=0;  }  //启动串口  

while(RI==0);  

  data5=SBUF;    

  RI=0;   

 while(RI==0);     

 data6=SBUF;     

 RI=0;    

 while(RI==0); 

   data7=SBUF;

  RI=0; 

 REN=0;   

 if(data1==0x00)  { data2=(data5&0xfc)>>2;   

  data3=(data6&0xfc)>>2; 

  data4=(data7&0xfc)>>2; }              }

else { for( a=0xff; a!=0x00; a--)

{   while(RI==0);   RI=0;  }  //启动串口      

    for( a=add; a!=0x00; a--) 

  {while(RI==0);      RI=0;  }  //启动串口  

  while(RI==0);   

   data5=SBUF;   

   RI=0;   

 while(RI==0);   

   data6=SBUF;  

    RI=0;   

 while(RI==0); 

   data7=SBUF; 

 RI=0;

  REN=0;   

 if(data1==0x00)  { data2=(data5&0xfc)>>2; 

    data3=(data6&0xfc)>>2; 

  data4=(data7&0xfc)>>2; }                 }

P1=0xff;           

     if(P3_5==0)            

    { mark=0x00;            add=P1; }        

     else  { mark=0xff;             add=P1; }   }  } 

  void main(void)   

{       P3=0x00;

 P3_0=1;

 P3_1=1;

 P3_5=1;     

 P1=0xff;

 if(P3_5==0)  

  { mark=0x00;  add=P1; }

else  { mark=0xff;        add=P1; }    

     SCON=0x88;

 ACC=PCON;

   ACC=ACC+0x80;

 PCON=ACC; //串口方式2 

  TMOD=0x21; // 定时器0方式1 定时器1方式

TH1=0x80; //60个周期中断一次

 TL0=0x80;

 TR1=1;

 IE=0x8a;  //允许允许T0中断

 do { do { start_bit();                   }     

   while(REN==0);}

while(1) ;}   

 //****************************************

//定时器T0  16bit 

 //****************************************

        void  t0_irq(void) interrupt 1 

   { t0_mark++;   

  time++;

 if (time>0x500) 

     { time=0x00;    

 data2=0x00;

 data3=0x00;

 data4=0x00; }     }

//***************************************

//定时器T1  方式2  自动重装, PWM  200Hz

//***************************************

void  t1_irq(void) interrupt 3

{ if(da1==0x00)    

  {P3_2=0;  }   

  else  {da1--;         P3_2=1; 

}if(da2==0x00)    {P3_3=0;  } 

 else  {da2--;          P3_3=1;

}if(da3==0x00)    {P3_4=0;  }   

 else  {da3--;         P3_4=1;}

 if(da4==0x00)   

  { da1=data2;    da2=data3;da3=data4; da4=0x40;  }da4--;           }

//实验程序 谨慎使用!

0
回复
a2895812
LV.2
17
2014-07-02 21:25
@a2895812
//**********************************************************//stc2051兼容ATMEL2051//16M晶振250k波特率//最简实验DMX512调光序//**********************************************************//P3_5-P10-511通道选择自动更新//P3_2P3_3P3_4RGB输出。//**********************************************************   #include   #define    ucharunsignedchar//**********************************************************//定义全局变量给中断程序使用。//**********************************************************   uchart0_mark=0x00, data1=0x00,data2=0x00,data3=0x00,data4=0x00,data5,data6,data7;  ucharda1=0x80,da2=0x80,da3=0x80,da4=0xff,mark=0x00,add=0x00;   unsigned int time;//*******************************************************//协议程序 //*******************************************************   voidstart_bit(void)   {uchara;   TR0=1;     while(P3_0==1);  //等待传输暂停 TR0=0;TH0=0x00;TL0=0x00;TR0=1;while (P3_0==0);//等待端口变化if(TL0>0x80||TH0>0x00) //大于96微秒   {REN=1;time=0x00;while(RI==0);    data1=SBUF;  if(mark==0x00)    {for(a=add;a!=0x00;a--){while(RI==0);  RI=0; } //启动串口  while(RI==0);   data5=SBUF;    RI=0;   while(RI==0);    data6=SBUF;    RI=0;    while(RI==0);   data7=SBUF; RI=0;  REN=0;   if(data1==0x00) {data2=(data5&0xfc)>>2;    data3=(data6&0xfc)>>2;   data4=(data7&0xfc)>>2;}       }else{for(a=0xff;a!=0x00;a--){  while(RI==0);  RI=0; } //启动串口      for(a=add;a!=0x00;a--)   {while(RI==0);   RI=0; } //启动串口   while(RI==0);    data5=SBUF;    RI=0;   while(RI==0);    data6=SBUF;    RI=0;   while(RI==0);   data7=SBUF;  RI=0; REN=0;   if(data1==0x00) {data2=(data5&0xfc)>>2;    data3=(data6&0xfc)>>2;   data4=(data7&0xfc)>>2;}         }P1=0xff;         if(P3_5==0)         {mark=0x00;      add=P1;}        else {mark=0xff;       add=P1;} } }   voidmain(void)  {    P3=0x00; P3_0=1; P3_1=1; P3_5=1;    P1=0xff; if(P3_5==0)   {mark=0x00; add=P1;}else {mark=0xff;    add=P1;}      SCON=0x88; ACC=PCON;   ACC=ACC+0x80; PCON=ACC;//串口方式2   TMOD=0x21;//定时器0方式1定时器1方式8 TH1=0x80;//60个周期中断一次 TL0=0x80; TR1=1; IE=0x8a; //允许允许T0中断 do{ do{ start_bit();          }     while(REN==0);}while(1);}   //****************************************//定时器T0 16bit  //****************************************      void t0_irq(void)interrupt1   {t0_mark++;    time++; if(time>0x500)    {time=0x00;    data2=0x00; data3=0x00; data4=0x00;}   }//***************************************//定时器T1 方式2 自动重装,PWM 200Hz//***************************************void t1_irq(void)interrupt3{if(da1==0x00)    {P3_2=0; }    else {da1--;     P3_2=1; }if(da2==0x00)  {P3_3=0; }  else {da2--;     P3_3=1;}if(da3==0x00)  {P3_4=0; }   else {da3--;     P3_4=1;} if(da4==0x00)    {da1=data2;  da2=data3;da3=data4; da4=0x40; }da4--;      }//实验程序谨慎使用!
DMX512.txt 排版惨不忍睹  文件上传吧,
0
回复
2014-07-18 17:03
@yueyunno1
前段时间在帖子上看到有人在谈论用单片机来做DMX512协议去控制LED灯,这几天刚好有点时间就写了个,有部分资料也来自网上
你好  你这个是不是和上面的电路图不匹配的呢?你那个R G B控制的引脚好像有点不对的呢?还问问你 想这种DMX一路的能传输多远的距离呢?是不是距离比较远的话就需要接连个DMX芯片一个作为输入 一个作为输出呢?
0
回复
a2895812
LV.2
19
2014-07-19 16:02
@辷噺一意
你好 你这个是不是和上面的电路图不匹配的呢?你那个RGB控制的引脚好像有点不对的呢?还问问你想这种DMX一路的能传输多远的距离呢?是不是距离比较远的话就需要接连个DMX芯片一个作为输入一个作为输出呢?

我不知道你是不是在问我,我这个程序是在控台上测试过的,是可以用的,DMX512协议规定在信号丢失多长时间后从设备应该自动关闭,这个程序里面也是有的,也就是说是按标准协议做的,但是测试不是完全,09年的时候刚出大学不久,水平有限,所以不建议使用这段程序。

管脚连接在程序的最前面我就标出来了,肯定和楼主的不兼容的,但只要按标名的管脚做外围就可以用了,具体我也多嘴说一下吧。

485总线按标准485总线电路连接即可,和楼主的应该一样,但也应该自己去看下485的标准接发。

P3_2 P3_3 P3_4是输出 注意极性,应接上拉电阻来驱动三极管,再驱动大功率三极管或者MOSFET,注意极性。

P3_5  和P1口  总共9个脚接DIP开关来设置地址,可以设置0-511地址,如果设置地址为32,则红色数据地址是32,绿色地址是33,蓝色地址是34;依此类推。

程序很乱,我自己都看不懂了。。。但是真的可以工作,还被我拿去卖了钱的。。。。。

0
回复
changlun
LV.7
20
2014-07-28 14:29
哈哈~ 这个不错。
0
回复
mht820413
LV.6
21
2014-08-09 09:23
@changlun
哈哈~这个不错。
不懂但是也顶顶,会C的电源工程师,是未来的趋势。电源也得智能化
0
回复
S112
LV.2
22
2014-09-10 11:37
@yueyunno1
原理图如下:[图片]
乐工,中断接入ISSI 402-3G这个芯片,不知道了解不?
0
回复
jag6510
LV.3
23
2015-01-02 10:29
@mht820413
不懂但是也顶顶,会C的电源工程师,是未来的趋势。电源也得智能化
顶顶顶
0
回复
yhy630
LV.2
24
2015-07-02 14:16
@a2895812
我不知道你是不是在问我,我这个程序是在控台上测试过的,是可以用的,DMX512协议规定在信号丢失多长时间后从设备应该自动关闭,这个程序里面也是有的,也就是说是按标准协议做的,但是测试不是完全,09年的时候刚出大学不久,水平有限,所以不建议使用这段程序。管脚连接在程序的最前面我就标出来了,肯定和楼主的不兼容的,但只要按标名的管脚做外围就可以用了,具体我也多嘴说一下吧。485总线按标准485总线电路连接即可,和楼主的应该一样,但也应该自己去看下485的标准接发。P3_2P3_3P3_4是输出注意极性,应接上拉电阻来驱动三极管,再驱动大功率三极管或者MOSFET,注意极性。P3_5 和P1口 总共9个脚接DIP开关来设置地址,可以设置0-511地址,如果设置地址为32,则红色数据地址是32,绿色地址是33,蓝色地址是34;依此类推。程序很乱,我自己都看不懂了。。。但是真的可以工作,还被我拿去卖了钱的。。。。。
谢谢楼主,要仔细研究一下.好好学习
0
回复
2016-02-20 19:34
还有好多不懂呢
0
回复
2016-02-21 15:22
看看 
0
回复
junfrom1989
LV.1
27
2016-03-14 14:49
@yueyunno1
前段时间在帖子上看到有人在谈论用单片机来做DMX512协议去控制LED灯,这几天刚好有点时间就写了个,有部分资料也来自网上
问一下 RB8是从哪里来的?

0
回复
zhck
LV.3
28
2017-09-30 17:12
@电子梦
正打算做DMX512的灯具,及时雨呀,网上也有很多资料,但是程序写得清晰明了的基本是没有的。

很好,不错学习了

0
回复
tanik
LV.5
29
2018-05-22 14:34

 学习了,多谢楼主分享!

0
回复
hjx5548
LV.4
30
2018-09-29 10:30
@a2895812
//**********************************************************//stc2051兼容ATMEL2051//16M晶振250k波特率//最简实验DMX512调光序//**********************************************************//P3_5-P10-511通道选择自动更新//P3_2P3_3P3_4RGB输出。//**********************************************************   #include   #define    ucharunsignedchar//**********************************************************//定义全局变量给中断程序使用。//**********************************************************   uchart0_mark=0x00, data1=0x00,data2=0x00,data3=0x00,data4=0x00,data5,data6,data7;  ucharda1=0x80,da2=0x80,da3=0x80,da4=0xff,mark=0x00,add=0x00;   unsigned int time;//*******************************************************//协议程序 //*******************************************************   voidstart_bit(void)   {uchara;   TR0=1;     while(P3_0==1);  //等待传输暂停 TR0=0;TH0=0x00;TL0=0x00;TR0=1;while (P3_0==0);//等待端口变化if(TL0>0x80||TH0>0x00) //大于96微秒   {REN=1;time=0x00;while(RI==0);    data1=SBUF;  if(mark==0x00)    {for(a=add;a!=0x00;a--){while(RI==0);  RI=0; } //启动串口  while(RI==0);   data5=SBUF;    RI=0;   while(RI==0);    data6=SBUF;    RI=0;    while(RI==0);   data7=SBUF; RI=0;  REN=0;   if(data1==0x00) {data2=(data5&0xfc)>>2;    data3=(data6&0xfc)>>2;   data4=(data7&0xfc)>>2;}       }else{for(a=0xff;a!=0x00;a--){  while(RI==0);  RI=0; } //启动串口      for(a=add;a!=0x00;a--)   {while(RI==0);   RI=0; } //启动串口   while(RI==0);    data5=SBUF;    RI=0;   while(RI==0);    data6=SBUF;    RI=0;   while(RI==0);   data7=SBUF;  RI=0; REN=0;   if(data1==0x00) {data2=(data5&0xfc)>>2;    data3=(data6&0xfc)>>2;   data4=(data7&0xfc)>>2;}         }P1=0xff;         if(P3_5==0)         {mark=0x00;      add=P1;}        else {mark=0xff;       add=P1;} } }   voidmain(void)  {    P3=0x00; P3_0=1; P3_1=1; P3_5=1;    P1=0xff; if(P3_5==0)   {mark=0x00; add=P1;}else {mark=0xff;    add=P1;}      SCON=0x88; ACC=PCON;   ACC=ACC+0x80; PCON=ACC;//串口方式2   TMOD=0x21;//定时器0方式1定时器1方式8 TH1=0x80;//60个周期中断一次 TL0=0x80; TR1=1; IE=0x8a; //允许允许T0中断 do{ do{ start_bit();          }     while(REN==0);}while(1);}   //****************************************//定时器T0 16bit  //****************************************      void t0_irq(void)interrupt1   {t0_mark++;    time++; if(time>0x500)    {time=0x00;    data2=0x00; data3=0x00; data4=0x00;}   }//***************************************//定时器T1 方式2 自动重装,PWM 200Hz//***************************************void t1_irq(void)interrupt3{if(da1==0x00)    {P3_2=0; }    else {da1--;     P3_2=1; }if(da2==0x00)  {P3_3=0; }  else {da2--;     P3_3=1;}if(da3==0x00)  {P3_4=0; }   else {da3--;     P3_4=1;} if(da4==0x00)    {da1=data2;  da2=data3;da3=data4; da4=0x40; }da4--;      }//实验程序谨慎使用!
能否加个寻址,方便级连。
0
回复
sabrina9988
LV.7
31
2018-11-10 15:50
支持一下
0
回复