This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSPM0G3519:RS485 通信失败

Guru**** 2873850 points

Other Parts Discussed in Thread: MSPM0G3519

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1637845/mspm0g3519-rs485-communication-fail

器件型号: MSPM0G3519

尊敬的 TI 实验者

我使用 MSPM03915 开发我的设计。 负责设计 RS485 通信。 该链包括一个主器件和三个从器件。 使用 MSPM0G3519 将三个从器件设计为相同的硬件和软件。 图中显示了通信连接。

image.png

我的问题如下图所示。 此过程可描述为以下步骤:

  1. 系统已启动。 所有的公社都是正确的。 主器件可将数据发送到三个从器件、三个从器件可将数据响应主器件。
  2. 经过一段时间后、便会创建错误通信。 在图片中、您可以看到所有从设备直接从主设备接收数据。 从器件 1 将其响应发送给主器件。 但是、从器件 2 和从器件 3 仅回顾从器件 1 的响应的最后四个字节。  
  3. 主器件需要从器件 2 的数据。 然而、从器件 2 和从器件 3 仅接收主器件数据的前五个字节。  
  4. 在此之后、只有从器件 1 可以工作。 从器件 2 和 3 的工作方式与步骤 2 和步骤 3 类似、错误。

我还检查数据总线中的数据。 而且、数据是正确的。

image.png

在我的设计中、DMA 轮询模式用于报告和发送 UART 数据。 通信的设计过程如下:

  1. 主设备将数据 1 发送到三个从设备来测量一些值。
  2. 主器件需要从器件 1 的数据、从器件 1 的响应需要。
  3. 主器件需要从器件 2 的数据、从器件 2 的响应要求。
  4. 主器件需要从器件 3 的数据、从器件 3 响应所需。
  5. 转到步骤 1。

请给出您的建议。 谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    DMA 在发送侧正常、但接收出现问题、因为任何错误都会使其混淆。

    我使用 DMA 进行 RS485 发送、但接收端使用中断和状态机。 和一个计时器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回答。 但是,它似乎没有解决我的问题。 您能根据我的案例分享一些经验和演示吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dengkuan:

    在 UART 通信过程中、似乎缺少了一些数据。

    如何在工程中配置 UART TXFIFO 和 RXFIFO、以及设置中 FIFO 的触发电平是多少?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    使用 DMA 进行接收很脆弱且容易损坏。

    当主器件将数据发送到从器件时、所有从器件都会接收到这些数据。 人们看着它,看到它是目标,并发送一个答复。

    其他从器件会查看数据、发现它们不是目标、并设置为接收另一个数据包。 但是、如果某个东西(可能是中断)延迟了该设置、该怎么办? 然后、它们会丢失数据包中的一个或多个字节。 如果它们不是重新同步的机制、则从器件永远不会恢复。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Rx FIFO 包含>=1 个条目

    Tx FIFO 包含 1 个条目

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果我不使用 DMA、您能分享一些处理该情况的示例吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我可以、但 Insert:代码编辑器功能对我不起作用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、David:

    您可以尝试压缩代码并将其拖放到聊天窗口中。

    尊敬的 Dengkuan:

    正如 Pengfei 提到的、最好向我们展示更多配置详细信息、最好提供一个可以在此处重现问题的简单演示代码。

    myside 还有一个问题是您是否尝试使用中断来处理按摩而不是 DMA?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Gary 和 Fengfei

    您可以参考这些信息。

    为了处理 UART 和 DMA:

    1、结构定义:


    uartBaseAddr = UART_Debug_INST、
    .txDataAddr =&UART_Debug_INST->TXDATA、
    .rxDataAddr =&UART_Debug_INST->RXDATA、

    .DMATxChannel_ID = DMA_CH3_CHAN_ID、
    .dmARxChannel_ID = DMA_CH2_CHAN_ID、
    .dmARxsize = RS485_RX_FRAME_SIZE、
    DMATx Channel_Interrupt 信号= DMA_CPU_INT_RIS_DMACH0_MASK、
    DMARx Channel_Interrupt 信号= DMA_CPU_INT_RIS_DMACH1_MASK、
    .irqn = UART_Debug_INST_INT_IRQN、

    }

    2. UART 的初始化:

    void UART_Init (UART_INDEX 常量 uartIndex)

    DL_DMA_clearInterruptStatus (DMA、UARTInst[uartIndex].DMATx Channel_Interrupt);
    DL_DMA_clearInterruptStatus (DMA、UARTInst[uartIndex].DMARx Channel_Interrupt);
    IF (UARTInst[uartIndex].irqn == UART_Debug_INST_INT_IRQN)

    NVIC_EnableIRQ (UARTInst[uartIndex].irqn);
    }


    UART_RX_DMA_cfg (uartIndex);
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的登光:

    而不会让人困惑的 while 循环代码

    我不知道在何处检查字节是命令字节还是地址字节。 配置 RX DMA 后、您可以使设备进入低功耗模式或检查一些标志以等待来自主机端的命令。 我在发送数据之前没有看到等待 RX 数据代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可以尝试压缩代码并将其拖放到聊天窗口中。

    /*  USCI receive interrupt handler
    
      Note that USCI_A0 and USCI_B0 share one vector.
    
      This is a bit more complicated since it handles receiving a complete 
      packet.
    
      The receive state machine:
    
      The state machine is a simple progression from one state to the next.
      Errors (timeout) result in a return to state zero.
    
      State     waiting for?
        0         nothing
        1         looking for SYNC character
        2         Reads up to length byte
        3         Reads remainder of packet
    
        Once a complete packet is recevied, an event is added to the queue. The
        main loop is then awakened so that it can examine the packet.
    */
     
    __attribute__((interrupt(USCI_A1_VECTOR))) void rxISR(void)
    {
      static int i, count;
      int c;
    
      switch(UCA1IV)
        {
        case USCI_UART_UCRXIFG:
          c = UCA1RXBUF;   // get the received character
          switch(rx_state)
            {
            case 0:     // Drop all received characters in state 0
              break;         
            case 1:     // scanning for SYNC character
              if(c == PSYNC)
                {
    	      TA2CCR1 = TA2R + CHAR_TIMEOUT;  // reset timeout timer
                  i = 0;
                  rx_state = 2;
                }
              break;
            case 2:
              TA2CCR1 = TA2R + CHAR_TIMEOUT;  // reset timeout timer
              RPacketBuf[i++] = c;
              if(i == 3)         // this should be the count of bytes in the data packet
    	                {
                  count = c+5;       // Don't forget the header and CRC
                  rx_state = 3;
                }
              break;
            case 3:
              TA2CCR1 = TA2R + CHAR_TIMEOUT;  // reset timeout timer
              if(i < BUFSIZE)     // Drop all characters that don't fit buffer
                RPacketBuf[i++] = c;
              if(i >= count)
                {
                  rx_state = 0;
                  recv_flag = RECV_OK;
                  TA2CCTL1 &= ~CCIE;  // disable compare interrupt
    	      WAKEUP;
                }
              break;
            default:
              rx_state = 0;
              recv_flag = RECV_IDLE;
            }
          break;
        case USCI_UART_UCTXIFG:
          break;
        case USCI_UART_UCSTTIFG:
          break;
        case USCI_UART_UCTXCPTIFG:
          if(UCA1IFG & UCTXIFG)
    	{
    	  LED2_OFF;
    	  P3OUT &= ~0x10;          // disable transmitter
    	}
          break;
        }
    }

    我又尝试了一次,这次我没有最终得到一个空白的字段。

    此代码适用于 MSP430、因此不直接适用于 MSPM0。 但我不是目前不评论代码的学校,所以它应该很容易遵循。

    主代码负责验证数据包校验和及地址是否正确。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Gary、

    我只是张贴主要而不包括一切. 我不希望器件进入低功耗模式。 为了检查某些标志、您能提供一些详细信息吗? memcpy 用于将 DMA 数据复制到需要处理的数据结构中。 当然、我没有写下详细信息。

    此外、我们希望能够面对面地讨论这一问题、因为这是非常紧迫的。 谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dengkuan:

    很抱歉、因为我上周不在办公室、所以回复太晚了。 正如我们离线讨论的、当前可以很好地触发 MCU UART Rx 中断。

    当前问题是通信期间仍然存在字节缺失问题。 我建议通过以下方式进行调试:

    •  使用大缓冲区记录从 UART 接收到的所有数据、并将其与 UART 波形进行比较。
    • 检查 UART 波形并检查 CTS 和 UART 信号之间的时序。
    • 检查它们是否在应用中禁用全局中断代码。

    此致、

    Pengfei