基于C51的DMX512开发笔记

来源:互联网 发布:将java项目打成jar 编辑:程序博客网 时间:2024/05/21 09:10

一、       DMX512协议

       DMX Digital MultipleX 的缩写,意为多路数字传输。DMX512控制协议是美国舞台灯光协会(usITT)于1990年发布的灯光控制器与灯具设备进行数据传输的工业标准,全称是USITTDMX5121990),包括电气特性、数据协议、数据格式等方面的内容。

      每一个DMX 控制字节叫做一个指令帧,称作一个控制通道,可以控制灯光设备的一个或几个功能。一个DMX 指令帧由1个开始位、8个数据位和2个结束位共11位构成,采用单向异步串行传输,如图1所示。

1 DMX512 定时程序的帧结构(上图)和信息包结构(下图)

 

       图1 中虚线内控制指令中的S 为开始位,宽度为一个比特,是受控灯具准备接收并解码控制数据的开始标志;E为结束位,宽度为两个比特,表示一个指令帧的结束;D0 D78位控制数据,其电平组合从0000~l1111111共有256个状态(对应十进制数的0255),控制灯光的亮度时,可产生256个亮度等级,0000~0)对应灯光最暗,l1111111255)对应灯光最亮。DMX512指令的位宽(每比特宽度)是4 us,每帧宽度为44 us,传输速率为250 kbps

       一个完整的DMX512信息包(Packet)由一个MTBP位、一个Break位、一个MAB位、一个SC512个数据帧构成。MTBPMark TimeBetween Packets)标志着一个完整的信息包发送完毕,是下一个信息包即将开始的“空闲位”,高电平有效。Break为中断位,对应一个信息包结束后的程序复位阶段,宽度不少于两个帧(22比特)。程序复位结束后应发送控制数据,但由于每一个数据帧的第一位(即开始位)为低电平,所以必须用一个高电平脉冲间隔前后两个低电平脉冲,这个起间隔、分离作用的高电平脉冲即MABMark After Break),此脉冲一到,意味着“新一轮”的控制又开始了。SCStart Code)意为开始代码帧(图1中的第0帧),和此后到来的数据帧一样,也是由11位构成,除两个高电平的结束位之外,其他9位全部是低电平,通常将其叫做第0帧或第0通道(Ch~nel No 0),可理解为一个不存在的通道(Non~istent Channe1)。

 

1 DMX512 信息包定时表

 

       表1 DMX512 信息包的定时表,表中NS意为Nm Spec~ed,宽度没有严格限制,由程序设计者自行决定,比如MTBP的宽度可以介于01秒之间。

       调光控制台每发送一个信息包,可以对全部512个受控通道形成一次全面的控制。发送一个信息包的时间大约是23 ms,每秒钟将对所有512个受控通道完成44次控制,即受控光路的刷新频率44 Hz,如果实际受控通道少于512个,那么刷新频率将相应提高。

 

二、       DMX512接口电路

        以下是使用RJ45连接器的接线及驱动电路 :

2 DMX512 设备使用RJ45连接器的接线表

 

 

2 DMX512 设备接口驱动电路

 

三、       C51开发的DMX512发送程序

// 串口工作在方式3void send_dmx (void) {unsigned int count;EA = 0;TXD = 1;//breakTXD = 0;Delay88us();TXD = 1;Delay8us();TB8 = 1;//MABSBUF = 0x00;while (!TI);TI = 0;for (count=0 ; count<max_circuit ; count++){TB8 = 1;SBUF = XBYTE[count];while(!TI);TI = 0;}TXD = 1;EA = 1;}

四、       C51开发的DMX512接收程序

// 串口工作在方式3void uart(void) interrupt 4{static bit flag = 0;if(RI)  {if(RB8 == 0) {if(SBUF == 0)flag = 1;//set flag when meet a breakRecv.count = 0;//reset uart data counter}else if (flag == 1) {if(Recv.count == 0) //byte after resetif(SBUF != 0) //not a start codeflag = 0; //error, reset flagif(Recv.count >= Recv.addr && Recv.count < Recv.addr + CTL_LEN)  {Recv.dat.Byte[Recv.count - Recv.addr] = SBUF;}If (Recv.count < 512)  Recv.count++;else  flag = 0;}RI = 0;}}


 

原创粉丝点击