DMX512输出协议详解

目录

​编辑

1、DMX512协议简介

2、DMX512协议分析

DMX512指令帧介绍

DMX512信息包

3、DMX512接口电路

4、参考代码


1、DMX512协议简介

DMX512是一种用于舞台灯光控制的数字传输协议。它是由美国舞台灯光协会(USITT)于1990年发布的工业标准,全称为USITT DMX512(1990)。DMX512协议定义了灯光控制器与灯具设备之间进行数据传输的电气特性、数据协议和数据格式等方面的内容。通过DMX512协议,可以实现对舞台灯光设备的精确控制,包括调整亮度、颜色、运动等。DMX512协议常用于舞台演出、演唱会、剧院等场合,以及其他需要对灯光进行精确控制的应用领域。

DMX512是一种用于控制舞台灯光和特效设备的通信协议。它在物理层采用EIA-485差分信号,并结合可变尺寸和基于分组的通信协议。DMX512是单向的,意味着只能从控制器发送数据到灯光和特效设备,而不能反向传输数据。

DMX512协议不包含自动错误检查和纠正功能,因此不适用于一些危险应用,如烟火或舞台装置的移动。电磁干扰、静电放电、不正确的电缆端接、电缆过长或电缆质量等因素可能会导致虚假触发或通信错误。


2、DMX512协议分析

DMX512指令帧介绍

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

图1 中虚线内控制指令中的S为开始位,宽度为一个比特,是受控灯具准备接收并解码控制数据的开始标志;

E为结束位,宽度为两个比特,表示一个指令帧的结束;

D0~ D7为8 位控制数据,其电平组合从00000000一11111111 共有256个状态(对应十进制数的0~255),控制灯光的亮度时,可产生256个亮度等级,0000~ (0)对应灯光最暗,11111111(255)对应灯光最亮。

DMX512指令的位宽(每比特宽度)是4 us,每一个指令帧11位,故指令帧宽度为44 us,传输速率为1/44us = 250 kbps。

DMX512信息包

一个完整的DMX512信息包(Packet)由一个MTBP位、一个Break 位、一个MAB位、一个SC 和512个数据帧构成。

MTBP(Mark TimeBetween Packets)标志着一个完整的信息包发送完毕,是下一个信息包即将开始的“空闲位”,高电平有效。

Break为中断位,对应一个信息包结束后的程序复位阶段,宽度不少于两个帧(22 比特)。程序复位结束后应发送控制数据,

MAB位,由于每一个数据帧的第一位(即开始位)为低电平,所以必须用一个高电平脉冲间隔前后两个低电平脉冲,这个起间隔、分离作用的高电平脉冲即MAB(Mark After Break),此脉冲一到,意味着“新一轮”的控制又开始了。

SC(Start Code)意为开始代码帧(图1中的第0帧),和此后到来的数据帧一样,也是由11 位构成,除最后的两个高电平的结束位之外,其他9位全部是低电平,通常将其叫做第0 帧或第0通道(Ch~nel No 0),可理解为一个不存在的通道(Non一~istent Channe1)。

DMX512 信息包定时表:

表1 是DMX512 信息包的定时表,表中NS意为自己设定,宽度没有严格限制,由程序设计者自行决定,比如MTBP的宽度可以介于0~1秒之间,其他建议采用典型值。

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

3、DMX512接口电路

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

(XLR-5和RJ45基本类似)

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

4、参考代码

#include "stm32f0xx.h"// 定义DMX512数据包长度
#define DMX_PACKET_LENGTH 512// 定义WS2812B LED串的数量
#define NUM_LEDS 8// 定义WS2812B数据包长度
#define WS2812B_PACKET_LENGTH (NUM_LEDS * 24)// 定义DMX512数据包缓冲区
uint8_t dmxPacket[DMX_PACKET_LENGTH];// 定义WS2812B数据包缓冲区
uint8_t ws2812bPacket[WS2812B_PACKET_LENGTH];// 初始化USART1
void USART1_Init(void) {// 启用USART1时钟RCC->APB2ENR |= RCC_APB2ENR_USART1EN;// 配置USART1引脚GPIOA->MODER |= GPIO_MODER_MODER9_1; // PA9作为USART1的TX引脚GPIOA->AFR[1] |= (1 << (4 * (9 - 8))); // 将PA9配置为USART1的TX引脚// 配置USART1USART1->BRR = 48000000 / 250000; // 设置波特率为250000USART1->CR1 |= USART_CR1_TE; // 使能发送USART1->CR1 |= USART_CR1_UE; // 使能USART1
}// 发送DMX512数据包
void DMX512_SendPacket(uint8_t *packet, uint16_t length) {for (uint16_t i = 0; i < length; i++) {while (!(USART1->ISR & USART_ISR_TXE)); // 等待发送缓冲区为空USART1->TDR = packet[i]; // 发送数据}
}// 初始化WS2812B
void WS2812B_Init(void) {// 配置GPIOA引脚0-7为推挽输出GPIOA->MODER |= GPIO_MODER_MODER0_0 | GPIO_MODER_MODER1_0 | GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0 |GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_0 | GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0;// 配置GPIOA引脚0-7的输出速度为高速GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 | GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3 |GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 | GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7;
}// 发送WS2812B数据包
void WS2812B_SendPacket(uint8_t *packet, uint16_t length) {for (uint16_t i = 0; i < length; i++) {uint8_t data = packet[i];for (uint8_t j = 0; j < 8; j++) {if (data & 0x80) {GPIOA->BSRR = GPIO_BSRR_BS_0; // 设置引脚为高电平__NOP(); // 空操作,延时约400nsGPIOA->BRR = GPIO_BRR_BR_0; // 设置引脚为低电平__NOP(); // 空操作,延时约850ns} else {GPIOA->BSRR = GPIO_BSRR_BS_0; // 设置引脚为高电平__NOP(); // 空操作,延时约850nsGPIOA->BRR = GPIO_BRR_BR_0; // 设置引脚为低电平__NOP(); // 空操作,延时约400ns}data <<= 1;}}
}int main(void) {// 初始化USART1USART1_Init();// 初始化WS2812BWS2812B_Init();while (1) {// 发送DMX512数据包DMX512_SendPacket(dmxPacket, DMX_PACKET_LENGTH);// 发送WS2812B数据包WS2812B_SendPacket(ws2812bPacket, WS2812B_PACKET_LENGTH);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/325874.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 日历组件

我们的需求是显示当前月和下个月的排班表 引入 uniapp 日历组件 uni-calendar 做法有两种&#xff0c;一种是直接去修改组件&#xff0c;还有就是文档中提供的 selected 方法 修改组件的就不写了 <uni-calendar :lunar"true" :selected"selected" :in…

助力实体店数字化升级,VR智慧门店打造线上逛店体验

近年来&#xff0c;传统实体店业绩增长过于缓慢&#xff0c;实体门店的销售疲态十分明显&#xff0c;甚至于部分城市已经出现大量线下实体店开始关门的现象&#xff0c;因此顺应实体零售数字化升级趋势已经刻不容缓。越来越多的实体门店开始意识到这个问题&#xff0c;并逐步开…

日程安排小程序实战教程

日常中我们经常有一些事情需要提醒自己&#xff0c;使用日历的形式比较符合实际的使用习惯。本篇我们就利用微搭低代码工具带着大家开发一款日程安排的小程序。 1 创建数据源 登录微搭低代码控制台&#xff0c;打开数据模型&#xff0c;点击创建 输入数据源的名称日程安排 …

MySQL进阶篇(二) 索引

一、索引概述 1. 介绍 索引&#xff08;index&#xff09;是帮助 MySQL 高效获取数据 的 数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数…

SpringBoot内嵌的Tomcat启动过程以及请求

1.springboot内嵌的tomcat的pom坐标 启动后可以看到tomcat版本为9.0.46 2.springboot 内嵌tomcat启动流程 点击进入SpringApplication.run()方法里面 看这次tomcat启动相关的核心代码refreshContext(context);刷新上下文方法 public ConfigurableApplicationContext run(Stri…

spark的任务提交方式及流程

本地模式 local 测试用,不多赘述 分布式模式 standalone standalone集群是spark 自带的一个资源调度集群&#xff0c;分为两个角色&#xff0c;master/worker&#xff0c;master负责接收任务请求、资源调度&#xff08;监听端口7077&#xff09;&#xff0c;worker负责运行exec…

win10报错“zlib.dll文件丢失,软件无法启动”,修复方法,亲测有效

zlib.dll文件是一个由Zlib创建的动态链接库文件&#xff0c;它是用于Windows操作系统的数据压缩和解压缩的软件。Zlib是一个广泛使用的软件库&#xff0c;广泛应用在许多不同类型的软件中&#xff0c;包括游戏、浏览器和操作系统。 zlib.dll的主要作用是提供数据压缩和解压缩的…

50N65-ASEMI高压N沟道MOS管50N65

编辑&#xff1a;ll 50N65-ASEMI高压N沟道MOS管50N65 型号&#xff1a;50N65 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 连续漏极电流(Id)&#xff1a;50A 漏源电压(Vdss)&#xff1a;650V 功率(Pd)&#xff1a;388W 芯片个数&#xff1a;2 引脚数量&#xff1a;…

Jupyter Lab | 在指定文件夹的 jupyter 中使用 conda 虚拟环境

Hi&#xff0c;大家好&#xff0c;我是源于花海。本文主要了解如何在指定文件夹的 jupyter 中使用 conda 虚拟环境&#xff0c;即在 conda 里面创建虚拟环境、将虚拟环境添加至 jupyter lab/notebook、安装软件包。 目录 一、创建虚拟环境 二、激活并进入虚拟环境 三、安装 …

差分约束算法

差分约束 差分约束系统包含 m m m个涉及 n n n个变量的差额限制条件&#xff0c;这些差额限制条件每个都是形式为 x i − x j ≤ b ∈ [ 1 , m ] x_i-x_j\leq b_{\in[1,m]} xi​−xj​≤b∈[1,m]​的简单线性不等式。 通常我们要求解出一组可行解。 最短路差分约束 如果我们…

Pygame和Cocos2d

Pygame和Cocos2d都是 Python 中常用的游戏引擎&#xff0c;但它们的设计目标、特点和使用场景略有不同。 Pygame与Cocos2d&#xff0c;目前是使用人数最多的两个Python游戏库。根据某知名产品点评网站的数据显示&#xff0c;排名前五的Python 2D游戏库如下图所示。其中&#x…

16.顺子日期(14)

题目 public class Main {public static boolean isLegal(String date) {int l 0;int n date.length();while(l<(n-3)) {int t1 (int)Integer.valueOf(date.substring(l,l1));int t2 (int)Integer.valueOf(date.substring(l1,l2));int t3 (int)Integer.valueOf(date.s…