目录

前言

一、项目简介

二、快速浏览

        1、总体结构

        2、头文件说明

        3、源文件说明

三、项目移植

总结


前言

        经过了近一年左右的学习,博主完成了一套相对成熟的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

总结

        本代码首次开源,有不成熟的地方还请包涵,有关源码相关的问题可以在评论区发送,我有空就会查看。祝大家开发顺利。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐