基于stm32实现DMX512协议发送与接收详解

发布时间:2023-05-10  

  STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核,其中STM32F系列有:STM32F103“增强型”系列STM32F101“基本型”系列STM32F105、STM32F107“互联型”系列,增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品;基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性能,是32位产品用户的最佳选择。两个系列都内置32K到128K的闪存,不同的是SRAM的最大容量和外设接口的组合。时钟频率72MHz时,从闪存执行代码,STM32功耗36mA,相当于0.5mA/MHz。

  基于stm32实现DMX512协议发送与接收

  DMX512数据协议是美国舞台灯光协会(USITT)于1990年发布的一种灯光控制器与灯具设备进行数据传输的标准。它包括电气特性,数据协议,数据格式等方面的内容。


  512协议规定使用的波特率是250Kbps,但是stm32可以支持shangMbps的波特率,所以说这不是什么大问题。


  该协议发送的数据帧一共11位,1位开始位,8位数据,2个停止位,无校验位。

  基于stm32实现DMX512协议发送与接收详解

  根据波特率可以知道,位时间是4us,11位数据供需要44us的时间。当然对于标准的512协议是需要break和mark after break 帧的,break是一个92us的低电平,而mark after break是一个12us的高电平,如下图所示

  基于stm32实现DMX512协议发送与接收详解

  基于stm32实现DMX512协议发送与接收详解

  根据上面的图片(缺失了起始码,下图补上),512协议必须有break和mark,但是在我们通常的非标准收发中,检测break和mark相对比较困难,如果非要做,耗费的资源也比较多,比如定时器计时,中断等等。如果不是做标准控制器的,完全可以另辟蹊径。

  基于stm32实现DMX512协议发送与接收详解

  根据512 协议,每一串数据的开始都要有一个起始码,也称复位码,其数据为0,但是从开始位数至第十位是0,用来声明数据传输开始,随后包含1-512个数据,也称调光数据,其是标准的数据帧,所以第十位是1,所以我们可以根据这个第十位来进行做文章。大家都知道,一般的单片机,像51,avr等都是支持8-9位数据发送的,所以我们就是用9位数据,1位停止位,无校验位,通过检测检测第十位,也就是所谓的RB8来进行数据的接收与传输,不需要发送break和mark。

  1、发送端

  串口设为 9位数据,1停止位,无校验位,波特率250000

  void USART1_Configuration(void)

  {

  USART_InitTypeDef USART_InitStructure;

  USART_InitStructure.USART_BaudRate = 250000;

  USART_InitStructure.USART_WordLength = USART_WordLength_9b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  /* Configure USART1 */

  USART_Init(USART1, &USART_InitStructure);

  /* Enable USART1 Receive and Transmit interrupts */

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  //USART_ITConfig(USART1, USART_IT_TC, ENABLE);

  /* Enable the USART1 */

  USART_Cmd(USART1, ENABLE);

  }

  注意在初始化串口的时候别忘了485芯片设为发送状态

  接下来主要就是数据包的发送,发送的时候注意起始码的数据第九位设为0,调光数据第九位设为1.

  void DMX_SendPacket(void)

  {

  pDMX_buf = 0;

  while (pDMX_buf 《= 512) //1-512

  {

  /* send data packet to slaves*/

  if(USART1-》SR & (1《《6))

  {

  /*发送起始码 00*/

  if (0 == pDMX_buf)

  {

  USART1-》DR = ((USART1-》DR) & 0xfe00); //第九位置0

  }

  else

  {

  USART1-》DR = 0x0100 | DMX_buf[pDMX_buf]; //第九位置1

  }

  pDMX_buf++;

  }

  }

  }

  以上函数相比大家都可以看懂,接下来就是在main函数中进行循环数据的发送了,比如每200ms发送一次,由于发送快,偶尔的错误也不是很明显。

  2,、接收端

  接收端得工作就是接收的信息进行解码(废话),关键是对RB8的处理,接收用到了中断接收,所以需要使能接收中断。

  void USART1_Configuration(void)

  {

  USART_InitTypeDef USART_InitStructure;

  USART_InitStructure.USART_BaudRate = 250000;

  USART_InitStructure.USART_WordLength = USART_WordLength_9b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  /* Configure USART1 */

  USART_Init(USART1, &USART_InitStructure);

  /* Enable USART1 Receive and Transmit interrupts */

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能接收中断

  //USART_ITConfig(USART1, USART_IT_TC, ENABLE);

  /* Enable the USART1 */

  USART_Cmd(USART1, ENABLE);

  }

  void NVIC_Configuration(void)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  #ifdef VECT_TAB_RAM

  /* Set the Vector Table base location at 0x20000000 */

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

  #else /* VECT_TAB_FLASH */

  /* Set the Vector Table base location at 0x08000000 */

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

  #endif

  //设置优先级分组:先占优先级和从优先级 ,先占优先级0位,从优先级4位

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  /* Enable the USART1 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  }

  void USART1_IRQHandler(void)

  {

  uint16_t UDR;

  static uint16_t RXB8;

  static uint16_t pDMX_buf = 0; //数据指针

  static uint8_t fDMX_buf_right = 0;

  //接收数据

  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//USART_FLAG_RXNE

  {

  //USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);

  UDR = USART_ReceiveData(USART1);

  RXB8 = (UDR & 0x0100);

  if (RXB8 == 0) //复位信号

  {

  if (!UDR)

  {

  fDMX_buf_right = 1;//接收数据正确

  pDMX_buf = 1; //直接接收第一个数据 不保存第0个数据。

  }

  }

  else //rb8 =1 pDMX_buf=1 调光数据

  {

  if (1 == fDMX_buf_right)

  {

  DMX_buf[pDMX_buf++] = (u8)UDR;

  //接收到512个数据

  if (pDMX_buf 》 512)

  {

  fDMX_buf_right = 0;

  tim_update = SET; //更新调光数据

  }

  }

  }

  }

  }


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    位,也可以通过状态机的方式来循环查询也可以。或者其他方式。 判断数据发送完成:   启动DMA并发送完后,产生DMA发送完成中断,在中断函数中做如下几件事:   1. 清DMA发送完成中断标志位 2. 关闭串口发送......
    ; //接收一帧数据的长度volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志uint8_trx1_buffer[BUFFER_SIZE]={0}; //接收......
    了。USART_FLAG_TC发送完成标志:这个才是代表USART在缓冲区的数据发送完成了,即从机接收到了数据。这两个标志的区别在于:它们分别表示数据在发送过程中,在两个不同的阶段中的完成......
    ] = ' ';         }                      gReceEndFlag = 0;   // 清除接收完成标志位         gReceCount = 0;   // 清零接收计数变量     } } 6.7 串口发送函数 //串口发送......
    /接收数据会请求DMA来完成数据的写和读。(注意这句话只针对本文!) 2、串口简要复习(库函数) 这里简要复习一下战舰STM32串口的知识点。举个例子:我想用PC机往STM32串口发送个数据,然后......
    (USART1,USART_FLAG_TC)==RESET);//上面清除了发送完成标志位,那么这里就可以等待发送完成标志位被置位来判断这一帧是否发完了 USART_SendData(USART1, 3......
      DMA_CleaRFlag(DMA1_FLAG_TC4); //清除完成标志   可以我的代码就这两部分,最后说一说我花了大半天才得到的调试记录:   1)使用DMA串口发送和单纯的串口发送......
    如何利用STM32单片机串口发送字符串;最近由于要调试一个SMS发送短信的模块,该模块需要发送一系列AT指令,且需要字符串发送,但是STM32官方给的usart.c中并没有直接发送字符串的函数,因此写了一个发送......
    参数错误;HAL_BUSY表示串口被占用; 注意事项 1. 函数将使能串口发送中断2. 函数将置位TXEIE和TCIE,使能发送数据寄存器空中断和发送完成中断。完成指定数量的数据发送后,将会关闭发送......
    中断处于关闭状态,当有数据需要发送的时候,先把数据先准备好存储在一个数组里面,然后调用发送函数。发送函数的内容先是把串口的中断打开(ES=1),清零发送完成标志位(TI = 0......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>