image.png

image.png

空闲位:没有DMX512数据包输出时,总线保持高电平
BREAK: 数据包的开始报头,维持88us的低电平。
MAB: 8us的高电平
Startcode:起始码:表示通道数据流的开始。
第N帧:通道n的调光数据。

STM32实现DMX512协议

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

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

image.png

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

1、初始化

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

  1. void USART1_Configuration(void) 2 {
  2. USART_InitTypeDef USART_InitStructure;
  3. USART_InitStructure.USART_BaudRate = 250000;
  4. USART_InitStructure.USART_WordLength = USART_WordLength_9b;
  5. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  6. USART_InitStructure.USART_Parity = USART_Parity_No;
  7. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  8. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  9. /* Configure USART1 */
  10. USART_Init(USART1, &USART_InitStructure);
  11. /* Enable USART1 Receive and Transmit interrupts */
  12. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  13. //USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  14. /* Enable the USART1 */
  15. USART_Cmd(USART1, ENABLE);
  16. }

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

2、数据包的发送

**

  1. 1 void DMX_SendPacket(void)
  2. {
  3. pDMX_buf = 0;
  4. while (pDMX_buf <= 512) //1-512
  5. {
  6. /* send data packet to slaves*/
  7. if(USART1->SR & (1<<6))
  8. {
  9. /*发送起始码 00*/
  10. if (0 == pDMX_buf)
  11. {
  12. USART1->DR = ((USART1->DR) & 0xfe00); //第九位置0
  13. }
  14. else
  15. {
  16. USART1->DR = 0x0100 | DMX_buf[pDMX_buf]; //第九位置1
  17. }
  18. pDMX_buf++;
  19. }
  20. }
  21. }

3、数据包的接收

**

  1. void USART1_Configuration(void)
  2. {
  3. USART_InitTypeDef USART_InitStructure;
  4. USART_InitStructure.USART_BaudRate = 250000;
  5. USART_InitStructure.USART_WordLength = USART_WordLength_9b;
  6. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  7. USART_InitStructure.USART_Parity = USART_Parity_No;
  8. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  9. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  10. /* Configure USART1 */
  11. USART_Init(USART1, &USART_InitStructure);
  12. /* Enable USART1 Receive and Transmit interrupts */
  13. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能接收中断
  14. //USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  15. /* Enable the USART1 */
  16. USART_Cmd(USART1, ENABLE);
  17. }
  18. void NVIC_Configuration(void)
  19. {
  20. NVIC_InitTypeDef NVIC_InitStructure;
  21. #ifdef VECT_TAB_RAM
  22. /* Set the Vector Table base location at 0x20000000 */
  23. NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  24. #else /* VECT_TAB_FLASH */
  25. /* Set the Vector Table base location at 0x08000000 */
  26. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  27. #endif
  28. //设置优先级分组:先占优先级和从优先级 ,先占优先级0位,从优先级4位
  29. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  30. /* Enable the USART1 Interrupt */
  31. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  32. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  33. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  34. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  35. NVIC_Init(&NVIC_InitStructure);
  36. }
  37. void USART1_IRQHandler(void)
  38. {
  39. uint16_t UDR;
  40. static uint16_t RXB8;
  41. static uint16_t pDMX_buf = 0; //数据指针
  42. static uint8_t fDMX_buf_right = 0;
  43. //接收数据
  44. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//USART_FLAG_RXNE
  45. {
  46. //USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);
  47. UDR = USART_ReceiveData(USART1);
  48. RXB8 = (UDR & 0x0100);
  49. if (RXB8 == 0) //复位信号
  50. {
  51. if (!UDR)
  52. {
  53. fDMX_buf_right = 1;//接收数据正确
  54. pDMX_buf = 1; //直接接收第一个数据 不保存第0个数据。
  55. }
  56. }
  57. else //rb8 =1 pDMX_buf=1 调光数据
  58. {
  59. if (1 == fDMX_buf_right)
  60. {
  61. DMX_buf[pDMX_buf++] = (u8)UDR;
  62. //接收到512个数据
  63. if (pDMX_buf > 512)
  64. {
  65. fDMX_buf_right = 0;
  66. tim_update = SET; //更新调光数据
  67. }
  68. }
  69. }
  70. }
  71. }