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.

[参考译文] TM4C123GH6PGE:带有 DMA TX 的 UART1丢失字节

Guru**** 2391465 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1019410/tm4c123gh6pge-uart1-lost-bytes-with-dma-tx

器件型号:TM4C123GH6PGE

我将 UART0配置 为通过 DMA 从外部器件发送和接收字节帧

然后、我还配置了 UART1、用于从 不同的外部器件发送和接收字节帧

57600  

有时 UART1传输一个没有某些字节的帧。 停止 UART0时、所有字节始终被发送。

每个 UART 都是以相同的方式配置的...这是 UART1

#define DMA_UART1_RX (22)// RX
#define DMA_UART1_TX (23)// TX

SysCtlPeripheralEnable (SYSCTL_Periph_UART1);


GPIOPinConfigure (GPIO_PC4_U1RX);
GPIOPinConfigure (GPIO_PC5_U1TX);
GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_4 | GPIO_PIN_5);


UARTConfigSetExpClk (UART1_base、SysCtlClockGet ()、57600、
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);

UARTFIFOLevelSet (UART1_base、UART_FIFO_TX4_8、UART_FIFO_RX4_8);

UARTTxIntModeSet (UART1_base、UART_TXINT_MODE_EOT);

UARTEnable (UART1_BASE);

UARTDMAEnable (UART1_BASE、UART_DMA_RX | UART_DMA_TX);
uDMAChannelAssign (UDMA_CH22_UART1RX);
uDMAChannelAssign (UDMA_CH23_UART1TX);

IntPrioritySet (INT_UART1、INT_PRIORY_LEVEL_5);

IntEnable (INT_UART1);

uDMAChannelAttributeDisable (EVO_DMA_UART1_RX、UDMA_ATTR_ALTSELECT |
uDMA_attr_USEBURST | uDMA_attr_high_priority | uDMA_attr_REQMASK);

uDMAChannelControlSet (EVO_DMA_UART1_RX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARC_4);

START_RX();

uDMAChannelAttributeDisable (EVO_DMA_UART1_TX、UDMA_ATTR_ALTSELECT |
uDMA_attr_USEBURST | uDMA_attr_high_priority | uDMA_attr_REQMASK);

uDMAChannelControlSet (EVO_DMA_UART1_TX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARC_4);

空 IntHandler_UART1 (空)

uint32_t ulStatus;
uint32_t ulMode;


ulStatus = UARTIntStatus (UART1_base、1);
UARTIntClear (UART1_base、ulStatus);

ulMode = uDMAChannelModeGet (DMA_UART1_RX | UDMA_PRI_SELECT);
如果(ulMode = UDMA_MODE_STOP)


START_RX1 ();

其他


if ((HWREG (UART1_BASE + UART_O_RIS)& UART_RIS_TXRIS)== UART_RIS_TXRIS)

uDMAChannelDisable (DMA_UART1_TX);


其他


uDMAIntClear ((1 << DMA_UART1_RX)|(1 << DMA_UART1_TX));

静态空 start_RX1 (空)


uDMAChannelDisable (EVO_DMA_UART1_RX);


UDMA_MODE_BASIC、
(void*)(UART1_base + UART_O_DR)、
rx1_bytes、
DIM_MAX_TXRX_Bytes);

uDMAChannelEnable (DMA_UART1_RX);

静态空 start_TX1 (uint32_t dim)




uDMAChannelTransferSet (DMA_UART1_TX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、
Tx1_bytes、
(void*)(UART1_base + UART_O_DR)、
DIM);

uDMAChannelEnable (DMA_UART1_TX);

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

    您好!

     这是我第一次遇到这样的问题。 您能回答几个问题吗?

     -除 UART0和 UART1外,还有其它 DMA 通道吗?

     -您能不能在不同波特率下重现同样的问题?  

     -您使用 basic_mode。 我建议您改为尝试 ping_pong 模式。 CPU 可能没有足够的时间来填充缓冲区、以便 UART1发送。 通常需要使用乒乓模式来处理这种情况。  

     -*如果使 UART1的中断优先级高于 UART0,该怎么办? 这是否会导致 UART1问题消失、而是使 UART0丢失字节?  

     -CPU 的工作时钟是多少? 是80MHz 还是更慢? 您能否使 CPU 以80MHz 的最大频率运行。

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

    您好、Charles、

    1)是的、我 也将 DMA 通道用于 UART5发送和接收。 我在 UART5上没有注意到同样的问题、但 UART5发送和接收非常短的字节帧。

    2) 2)今天、我将尝试不同的波特率

    3) 3)我在 pingpong 模式下也有相同的问题

    4) 4)我正在使用80MHz 的系统时钟

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

    我禁用了 UART0和 UART1上的 TX、也禁用了 UART5

    然后我又在 UART0 (不仅在 UART1上)的 RX 上激活了乒乓模式,我开始遇到了很多问题.....

    这  是 UART0的配置(UART1等效):

    uint8_t uart0_Rx_Bytes[DIM_MAX_RX_Bytes];

    空 UART0_Init (空)


    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);


    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);


    UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、57600、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);


    UARTFIFOLevelSet (UART0_BASE、UART_FIFO_TX4_8、UART_FIFO_RX4_8);


    UARTEnable (UART0_BASE);


    UARTDMAEnable (UART0_BASE、UART_DMA_RX | UART_DMA_TX);
    uDMAChannelAssign (UDMA_CH8_UART0RX);
    uDMAChannelAssign (UDMA_CH9_UART0TX);


    IntPrioritySet (INT_UART0、INT_PRIORY_LEVEL_UART0);


    IntEnable (INT_UART0);


    uDMAChannelAttributeDisable (UDMA_CHANGE_UART1RX、UDMA_ATTR_ALTSELECT |
    uDMA_attr_USEBURST | uDMA_attr_high_priority | uDMA_attr_REQMASK);


    uDMAChannelControlSet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT、
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARC_4);


    uDMAChannelControlSet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT、
     UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARC_4);


    uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT、
     UDMA_MODE_PINGONG、
    (void*)(UART0_BASE + UART_O_DR)、
       uart0_Rx_Bytes、
      DIM_MAX_RX_Bytes/2);

     uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT、
    UDMA_MODE_PINGONG、
     (void*)(UART0_BASE + UART_O_DR)、
    uart0_Rx_Bytes[DIM_MAX_RX_Bytes/2]、
    DIM_MAX_RX_Bytes/2);


    空 IntHandler_UART0 (空)

    uint32_t ulStatus;
    uint32_t ulMode;


    ulStatus = UARTIntStatus (UART0_BASE、1);
    UARTIntClear (UART0_BASE、ulStatus);


    ulMode = uDMAChannelModeGet (UDMA_CHANGE_UART0RX| UDMA_PRI_SELECT);
    如果(ulMode = UDMA_MODE_STOP)


    uDMAChannelTransferSet (UDMA_CHANGE_UART0RX| UDMA_PRI_SELECT、
    UDMA_MODE_PINGONG、
    (void *)(UART0_BASE + UART_O_DR)、
    uart0_Rx_Bytes、DIM_MAX_TXRX_Bytes/2);

    其他



    ulMode = uDMAChannelModeGet (UDMA_CHANGE_UART0RX| UDMA_ALT_SELECT);
    如果(ulMode = UDMA_MODE_STOP)


    uDMAChannelTransferSet (UDMA_CHANGE_UART0RX| UDMA_ALT_SELECT、
    UDMA_MODE_PINGONG、
    (void *)(UART0_BASE + UART_O_DR)、
    uart0_Rx_Bytes[DIM_MAX_RX_Bytes/2]、DIM_MAX_RX_Bytes/2);

    其他





    #define  INT_PRIORY_LEVEL_UART0  (0xA0)

    #define INT_PRIORY_LEVEL_UART1 (0xA0)

    到达时,UART0上的中断同时执行 PRI 和 ALT!!!  

    我有疑问....

    如何从数据表中解释这一点?

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

    您好!  

     在 UART0_Init 中、您有几个 UART1引用。 请参见下面的。  

    空 UART0_Init (空)


    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);


    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);


    UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、57600、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);


    UARTFIFOLevelSet (UART0_BASE、UART_FIFO_TX4_8、UART_FIFO_RX4_8);


    UARTEnable (UART0_BASE);


    UARTDMAEnable (UART0_BASE、UART_DMA_RX | UART_DMA_TX);
    uDMAChannelAssign (UDMA_CH8_UART0RX);
    uDMAChannelAssign (UDMA_CH9_UART0TX);


    IntPrioritySet (INT_UART0、INT_PRIORY_LEVEL_UART0);


    IntEnable (INT_UART0);


    uDMAChannelAttributeDisable (UDMA_CHANGE_UART1RX、UDMA_ATTR_ALTSELECT |
    uDMA_attr_USEBURST | uDMA_attr_high_priority | uDMA_attr_REQMASK);


    uDMAChannelControlSet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT、
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARC_4);


    uDMAChannelControlSet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT、
     UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARC_4);


    uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT、
     UDMA_MODE_PINGONG、
    (void*)(UART0_BASE + UART_O_DR)、
       uart0_Rx_Bytes、
      DIM_MAX_RX_Bytes/2);

     uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT

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

    很抱歉 、我在邮件中附上了错误 的部分...在我的真实代码中、我使用了正确的 UART!!

    在我的真实代码中,我有很多定义..为了澄清,我尝试用...

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

    您好!

    您能否再次确认、当 UART1是唯一运行的模块时、一切正常。 是这样吗?

    当您说 UART1不工作-缺少一些字节时、您能否详细说明您尝试传输的字节数量以及缺失的字节数量?   

    我之前要求更改 UART1的中断优先级。 您有机会这样做吗? 我要求更改优先级的原因是、如果停止 UART0、表示 UART1正在工作。 因此、除了 UART1的中断优先级之外、我没有理由相信任何错误配置 UART1。

    我看到下面的代码行。  

    IntPrioritySet (INT_UART1、INT_PRIORY_LEVEL_5);

    如果 UART0的优先级较高、则 UART1中断服务的机会将不相等。 是否可以使 UART0和 UART1具有相同的优先级、以便它们都能得到相同的服务? 在相同的优先级下、NVIC 将在模块之间循环。 这会产生影响吗?

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

    你(们)好

    1) 1)我确认、如果 UART1是唯一的操作模块、一切都正常、而当 UART0是唯一的操作模块时、一切都正常。

    2)两个模块具有相同的优先级、没有任何变化

    3) 3)如果我有 UART5和 UART 1、则两种操作方式都正常。 因此问题似乎出在 UART0上

    4) 4)如果 UART0和 UART1同时处于 RX 交替模式、则没有任何操作...当我说什么也不打算两个通道都接收到正确的字节...接收到的字节是随意或重复的、有时也没有接收到...

    当我在 UART0上接收到第一个中断时、问题开始。。。即使同一优先级或具有更高优先级的 UART1或具有更高优先级的 UART0也是如此

    5) 5)查看工作内容的唯一方法是在 RX 基本模式下使用 UART0、在 RX 交替或基本模式下使用 UART1、但在 UART0 INT 处理程序中使用如下所示:

    void IoT_IntHandler_UART0 (void)

    uint32_t ulStatus;


    ulStatus = UARTIntStatus (UART0_BASE、0);
    UARTIntClear (UART0_BASE、ulStatus);

    //leggo lo stato degli 中断 del DMA
    ulStatus = uDMAIntStatus();

    if (((ulStatus &(1 << UDMA_CHANGE_UART0RX))!= 0)

      START_IOT_RX ();
      uDMAIntClear (ulStatus &(1 << UDMA_CHANNEL UART0RX));

    其他;

    和 UART1 INT 处理程序一样正常(在乒乓模式下低于此值)

    空 IntHandler_UART1 (空)

    uint32_t ulStatus;
    uint32_t ulMode;


    ulStatus = UARTIntStatus (UART1_base、1);
    UARTIntClear (UART1_base、ulStatus);


    ulMode = uDMAChannelModeGet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT);
    如果(ulMode = UDMA_MODE_STOP)


    uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_PRI_SELECT、
    UDMA_MODE_PINGONG、
    (void *)(UART1_base + UART_O_DR)、
    uart1_Rx_Bytes、DIM_MAX_TXRX_Bytes/2);

    其他



    ulMode = uDMAChannelModeGet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT);
    如果(ulMode = UDMA_MODE_STOP)


    uDMAChannelTransferSet (UDMA_CHANGE_UART1RX| UDMA_ALT_SELECT、
    UDMA_MODE_PINGONG、
    (void *)(UART1_base + UART_O_DR)、
    uart1_Rx_Bytes[DIM_MAX_RX_Bytes/2]、DIM_MAX_RX_Bytes/2);

    其他

    //UART1通道为半双工、因此我需要截取传输结束;因此我启用了中断  

    // se e finita la trasionone su UART1 riattivo la ricezione
    if ((HWREG (UART1_BASE + UART_O_RIS)& UART_RIS_TXRIS)== UART_RIS_TXRIS)


    Evo_TX = false;
    // 启用瞬变器上的接收
    DIS_EVO_TX ();
    En_EVO_RX ();

    其他



    这样看起来一切正常、但有时当 UART1发送字节时、 在一个字节帧的中间、4或5个字节不会被发送。

    我以与 UART0相同的方式在 UART1上开始传输(对于 UART0、下面的内容):

    静态空 start_UART0_TX (uint32_t dim)


    uDMAChannelTransferSet (IOT_DMA_UART0_TX | UDMA_PRI_SELECT、
    UDMA_MODE_BASIC、
    IoT_TX_Bytes、
    (void*)(UART0_BASE + UART_O_DR)、
    DIM);


    uDMAChannelEnable (IOT_DMA_UART0_TX);

    为了在 UART1结束传输字节时产生中断、我在 UART1配置函数中添加了此行:

    UARTTxIntModeSet (UART1_base、UART_TXINT_MODE_EOT);

    在示波器的照片下方、当 UART1 TX 丢失要发送的字节...(在 UART0 TX 结束前5个字节)

    黄色 UART1 RX

    红色/粉色 UART1 TX

    绿色 UART0 TX

    青色 UART1 RX

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

    您好 Lisa、

     您能否上传另一个示波器快照以使信号不重叠? 当您有4个信号相互重叠时、我很难看到会发生什么情况。 如果问题出在 TX 上、则无需显示 RX 引脚。 还请指明要以什么值代替缺失的字节。  

     我真的不知道为什么要添加 UART0 break UART1。 起初、我在考虑中断优先级、但您证明情况并非如此。  

      您可以尝试一个简单的示例吗? 以 TivaWare UDMA_DEMO 示例为例、除 UART1外、还添加了 UART0。  您是否会看到任何缺失的字节?该示例还具有存储器到存储器之间的 DMA 传输、您可以将其删除。 该示例已在乒乓模式下将 DMA 传输到 UART1。 您是否看到了相同的问题?