嵌入式平台DMX&RDM协议开源项目说明
目录
前言
经过了近一年左右的学习,博主完成了一套相对成熟的DMX协议+RDM协议的驱动模块,现在将源码开放给大家学习,共同进步。
github仓库地址:https://github.com/murongbaibai/dmx-rdm.git
拉取命令:git clone https://github.com/murongbaibai/dmx-rdm.git
一、项目简介
本项目实现了标准DMX协议的收发,RDM协议的基础九大命令(搜寻设备、哑音设备、解除哑音设备、获取设备支持命令列表、获取设备命令类型定义、获取设备信息、获取设备软件版本、获取和设置设备DMX地址、获取和设置设备状态),以及扩展的一个命令(获取和设置设备模式)。本项目能够应用到舞台的各类设备的开发之中,也可作为设备之间的通信协议使用。
本项目适用于小型的嵌入式平台,整体体积较小,对主频的要求也不算很高(单路接收发送)。下面是项目移植要求:
| RAM(做输入设备,如灯板、摇头灯、帕灯) | >= 4K |
| RAM(做输出设备,如控台、RDM拨码器) | >= 8K |
| FLASH | >= 16K |
| 主频 | >= 24MHZ |
二、快速浏览
1、总体结构
本项目的源码结构十分简单,只有两个文件夹,inc存放头文件,src存放源文件。dmx_rdm.h为公共头文件,uart_init_template.c为串口初始化示例文件。

2、头文件说明
dr_config.h:链路配置文件,DMX协议和RDM协议的相关配置,设备通道数,模式数等。
dr_internel.h:相当于项目内部的mian.h,整合了其他头文件。
其他:对应源文件的头文件
3、源文件说明
dmx.c:DMX协议相关接口实现。
dr_line.c:链路初始化、模式切换、串口接收、发送、解包相关接口实现。
rdm.c:RDM协议收发相关接口实现。
rdm_input.c:RDM协议做从机的相关接口实现。
rdm_output.c:RDM协议做主机的相关接口实现。
dr_task.c:链路状态机实现,采用心跳时钟接口+主循环任务处理实现。
三、项目移植
首先下载代码到本地,将dmx-rdm模块复制到你们的工程文件中,这里以keil为例。
首先复制模块到工程路径中,然后打开keil工程

在keil工程中新建一个组,然后将项目源码中的src目录下的所有文件添加到新建的组“dmx-rdm”中。

接着在include path中添加源码头文件的路径,选择你保存的项目源码的位置,选择dmx-rmd文件夹。

还需要实现任务处理函数,和心跳时钟函数。可以将任务处理函数放到主循环中,将心跳时钟函数放到系统心跳时钟中(传入中断触发频率)。
void SysTick_Handler(void)
{
HAL_IncTick();
dr_tick_inc(1);
}
while(1)
{
//...
dr_task_handle();
vTaskDelay(5);
}
移植完成后就需要进行最困难的一步了,需要根据你的硬件平台完成串口初始化代码,具体的初始化配置可以参考uart_init_template.c文件,下面给出串口配置的要求。
| 波特率 | 250000 |
| 停止位 | 2位 |
| 数据位 | 8位 |
| 校验位 | 无 |
| 接收方式 | 支持中断接收和阻塞接收,DMA接收也支持,但是效率不高 |
| 发送方式 | 支持DMA发送、中断发送、阻塞发送 |
初始化完成后需要根据对应的中断请求来调用对应的处理函数,中断发送、接收方式实现参考如下。
void USART2_IRQHandler(void)
{
//实现断开信号检测接口
if(huart2.Instance->CR2 & USART_CR2_LBDIE)
{
if(huart2.Instance->SR & USART_SR_LBD)
{
//清除标志位
__HAL_UART_CLEAR_FLAG(&huart2,USART_SR_LBD);
DMX_UART_BreakHandle(dmx_line1);
}
}
HAL_UART_IRQHandler(&huart2);
}
//实现发送完成接口
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
DMX_UART_TxCompleteHandle(dmx_line1);
}
//实现接收完成接口
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
DMX_UART_RxCompleteHandle(dmx_line1);
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
//实现错误重启接口
if(huart->Instance == USART2)
DMX_UART_ErrorRebootHandle(dmx_line1);
}
如果是阻塞发送/接收,可以直接在发送接收完成后调用接口。
最后接收到对应的信号就会进行自动处理然后触发相应的回调函数,回调函数在uart_init_template.c中也有定义。
/******************************** 对用户开放的回调函数(在中断环境中回调、代码需要简短) ********************************/
//发送前回调函数,用于修改发送数组
void DMX_Send_Before_Callback(dmx_line_t *dmx_line)
{
}
//RDM解包完成回调函数
void RDM_UnpackComplete_Callback(dmx_line_t *dmx_line)
{
}
//DMX解包完成回调函数
void DMX_UnpackComplete_Callback(dmx_line_t *dmx_line)
{
}
#ifdef USE_REFRESH_TIM
//断开信号时间到回调
void DMX_Refresh_Tim_CompleteHandle(dmx_line_t* dmx_line)
{
}
#endif
总结
本代码首次开源,有不成熟的地方还请包涵,有关源码相关的问题可以在评论区发送,我有空就会查看。祝大家开发顺利。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)