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.

[参考译文] TM4C129XNCZAD:无法为 DMA 配置 UART5

Guru**** 2460380 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/649569/tm4c129xnczad-not-able-to-configure-uart5-for-dma

器件型号:TM4C129XNCZAD

该代码只是对 TM4C129X 库中的 DMA_DEMO 进行的修改、UART0工作正常。 但 UART5不是。 配置部件中缺少任何内容?

我检查了 TX 输出引脚、没有信号输出、始终为高电平(3.3V)

用于接收的 ISR

空 UART5IntHandler (空)

   uint32_t ui32Status1;
      uint32_t ui32mode1;

      //
      //读取 UART 的中断状态。
      //
      ui32Status1 = ROM_UARTIntStatus (UART5_BASE、1);
      //UARTIntDisable (UART0_BASE);

      IF (ui32Status1 = 0x00020000)
      {

          //在这里做点事情..........
          ROM_UARTDMADisable (UART5_BASE、UART_DMA_TX);
          //需要此步骤才能退出中断。
          ROM_UARTIntClear (UART5_BASE、ui32Status1);

          返回;
      }

      //HWREG (UART0_BASE + UART_O_ICR)= 0x00020000;
      //ui32Status = ROM_UARTIntStatus (UART0_BASE、1);

      //
      //清除任何挂起状态,即使由于没有 UART,应该没有任何挂起状态
      //中断已启用。  如果启用了 UART 错误中断
      //这些中断可能在这里发生,应该被处理。  UDMA 的影响
      //用于 RX 和 TX、那么这两个中断都不应该
      //已启用。
      //
      ROM_UARTIntClear (UART5_BASE、ui32Status1);
      ui32Status1 = ROM_UARTIntStatus (UART5_BASE、1);

      //
      //检查 DMA 控制表以查看乒乓"A"传输是否为
      //完成。  "A"传输使用接收缓冲器"A"和主缓冲器
      //控制结构。
      //
      ui32mode1 = ROM_uDMAChannelModeGet (UDMA_CH6_UART5RX | UDMA_PRI_SELECT);

      //
      //如果主控制结构体指示停止,则表示"A"
      //接收缓冲完成。  UDMA 控制器仍应接收
      //将数据输入"B"缓冲区。
      //
      if (ui32mode1 = udma_mode_stop)
      {
          //
          //递增计数器以指示数据已接收到缓冲区 A 中  
          //一个实际应用,此应用将用于向主线程发出信号
          //数据已接收,因此主线程可以处理数据。
          //-------------------- >在缓冲区 A-->???中设置接收到的数据标志

          //g_ui32RxBufACount++;

          //
          //使用主缓冲区为"A"缓冲区设置下一个传输
          //控制结构。  进入"B"缓冲器的持续接收为时
          //完成,UDMA 控制器将切换回这个。  这种情况
          //示例重复使用缓冲区 A,但更复杂的应用可能
          //使用一组旋转的缓冲区来增加该时间
          //主线程必须先处理缓冲区中的数据,然后再处理
          //重复使用。
          //
          ROM_uDMAChannelTransferSet (UDMA_CH6_UART5RX | UDMA_PRI_SELECT、
          UDMA_MODE_PINGONG、
                                     (void *)(UART5_BASE + UART_O_DR)、
                                     G_ui8pMeterRxBufA、
                                     sizeof (g_ui8pMeterRxBufA));
      }

      //
      //检查 DMA 控制表以查看乒乓"B"传输是否为
      //完成。  "B"传输使用接收缓冲器"B"和副缓冲器
      //控制结构。
      //
      ui32mode1 = ROM_uDMAChannelModeGet (UDMA_CH6_UART5RX | UDMA_ALT_SELECT);

      //
      //如果副控制结构体指示停止,则表示"B"
      //接收缓冲完成。  UDMA 控制器仍应接收
      //将数据输入到"A"缓冲区中。
      //
      if (ui32mode1 = udma_mode_stop)
      {
          //
          //递增计数器以指示数据已接收到缓冲区 A 中  
          //一个实际应用,此应用将用于向主线程发出信号
          //数据已接收,因此主线程可以处理数据。
          //
          //g_ui32RxBufBCount++;

          ///---------- >设置接收到的数据标志-->???

          //使用替代设置"B"缓冲区的下一个传输
          //控制结构。  接收到"A"缓冲器的时间
          //完成,UDMA 控制器将切换回这个。  这种情况
          //示例重复使用缓冲区 B,但更复杂的应用程序可以
          //使用一组旋转的缓冲区来增加该时间
          //主线程必须先处理缓冲区中的数据,然后再处理
          //重复使用。
          //
          ROM_uDMAChannelTransferSet (UDMA_CH6_UART5RX | UDMA_ALT_SELECT、
          UDMA_MODE_PINGONG、
                                     (void *)(UART5_BASE + UART_O_DR)、
                                     G_ui8pMeterRxBufB、
                                     sizeof (g_ui8pMeterRxBufB));
      }

      //
      //如果 UART0 DMA TX 通道被禁用,则表示 TX DMA 传输
      //完成。
      //

      //必须重新启用 uDMA TX 通道。
      //

  }

//函数使用 DMA 将 UART 5配置为写入和读取

空 InitUART5传输(空)

   //为仪表 UART 配置器件引脚
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);

           ROM_GPIOPinConfigure (GPIO_PC6_U5RX);
           ROM_GPIOPinConfigure (GPIO_PC7_U5TX);
           ROM_GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_6 | GPIO_PIN_7);

       //启用 UDMA UART 并将其配置为即使 CPU 处于睡眠状态也能正常工作
           ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UDMA);
           ROM_SysCtlPeripheralSlepEnable (SYSCTL_Periph_UDMA);

           ROM_IntEnable (INT_UDMAERR);

            //
            //启用 UDMA 控制器。
            //
           ROM_uDMAEnable();


           ROM_uDMAControlBaseSet (pui8ControlTable);

           ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART5);
           ROM_SysCtlPeripheralSlepEnable (SYSCTL_Periph_UART5);

           //配置 UART 通信参数。
           //
           ROM_UARTConfigSetExpClk (UART5_BASE、ui32SysClock、9600、
           UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
           UART_CONFIG_PAR_NONE);

   //启用 uDMA 控制器错误中断。  将发生该中断
   //如果在传输过程中出现总线错误。
   //

   //
   //指向控制表以用于通道控制结构体。
      //

   //
   //将 TX 和 RX 触发阈值设置为4。  这将由使用
   // uDMA 控制器发出信号,指示何时应传输更多数据。  。
   //将配置 uDMA TX 和 RX 通道,以便可以传输4个通道
   当 UART 准备传输更多数据时、//以突发方式传输字节。
   //
   ROM_UARTFIFOLevelSet (UART5_BASE、UART_FIFO_TX1_8、UART_FIFO_RX1_8);

   //
   //启用 UART 以进行操作,并为两个 TX 启用 UDMA 接口
   //和 RX 通道。
   //
   ROM_UARTEnable (UART5_BASE);
   //ROM_UARTDMAEnable (UART0_BASE、UART_DMA_RX);
   ROM_UARTDMAEnable (UART5_BASE、UART_DMA_RX | UART_DMA_TX);
   //
   //该寄存器写入将 UART 设置为在写入模式下运行。
   //
   //HWREG (UART0_BASE + UART_O_CTL)|= UART_CTL_TXE;

   //
   //将 UDMA UART0RX 通道的属性置于已知状态。  这些
   默认情况下、//应已禁用。
   //
   ROM_uDMAChannelAttributeDisable (UDMA_CH6_UART5RX、
   UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
   UDMA_ATTR_HIGH_PRIOR|
   UDMA_ATTR_REQMASK);

   //
   //为配置主控制结构体的控制参数
   // UART RX 通道。  主控制结构用于"A"
   //部分乒乓接收。  传输数据大小为8位
   //源地址不会递增,因为它将从读取
   //寄存器。  目的地址增量是字节8位字节。  。
   //仲裁大小设置为4以匹配 RX FIFO 触发阈值。
   //如果可能,UDMA 控制器将使用4字节突发传输。  这种情况
   //这种单字节传输会更有效一些。
   //
   ROM_uDMAChannelControlSet (UDMA_CH6_UART5RX | UDMA_PRI_SELECT、
   UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
   UDMA_ARB_1);

   //
   //为的替代控制结构配置控制参数
   // UART RX 通道。  备用控制结构体用于"B"
   //部分乒乓接收。  配置与相同
   //主/A 控制结构。
   //
   ROM_uDMAChannelControlSet (UDMA_CH6_UART5RX | UDMA_ALT_SELECT、
   UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
   UDMA_ARB_1);

   //
   //设置 UART RX 主控件的传输参数
   //结构。  模式设置为乒乓模式、传输源为
   // UART 数据寄存器,目的是接收“A”缓冲区。  。
   //传输大小设置为与缓冲区大小匹配。
   //
   ROM_uDMAChannelTransferSet (UDMA_CH6_UART5RX | UDMA_PRI_SELECT、
   UDMA_MODE_PINGONG、
                              (void *)(UART5_BASE + UART_O_DR)、
                              g_ui8pMeterRxBufA、sizeof (g_ui8pMeterRxBufA);

   //
   //设置 UART RX 交替控制的传输参数
   //结构。  模式设置为乒乓模式、传输源为
   // UART 数据寄存器,目的是接收"B"缓冲区。  。
   //传输大小设置为与缓冲区大小匹配。
   //
   ROM_uDMAChannelTransferSet (UDMA_CH6_UART5RX | UDMA_ALT_SELECT、
   UDMA_MODE_PINGONG、
                              (void *)(UART5_BASE + UART_O_DR)、
                              g_ui8pMeterRxBufB、sizeof (g_ui8pMeterRxBufB);

   //
   //将 UDMA UART0TX 通道的属性置于已知状态。  这些
   默认情况下、//应已禁用。
   //
   ROM_uDMAChannelAttributeDisable (UDMA_CH7_UART5TX、
   UDMA_ATTR_ALTSELECT |
   UDMA_ATTR_HIGH_PRIOR|
   UDMA_ATTR_REQMASK);

   //
   //设置 UDMA UART TX 通道的 USEBURST 属性。  这将会
   //强制控制器在传输数据时始终使用突发
   //将 TX 缓冲器连接到 UART。  这是比较有效的总线使用
   //不是允许单次或突发传输的默认值。
   //
   ROM_uDMAChannelAttributeEnable (UDMA_CH7_UART5TX、UDMA_ATTR_USEBURST);

   //
   //配置 UART TX 的控制参数。  UDMA UART TX
   //通道用于将数据块从缓冲区传输到 UART。
   //数据大小为8位。  源地址增量为8位字节
   //因为数据来自缓冲区。  目的增量为
   //由于数据将被写入 UART 数据寄存器,因此不存在。  。
   //仲裁大小设置为4,与 UART TX FIFO 触发器匹配
   //阈值。
   //
   ROM_uDMAChannelControlSet (UDMA_CH7_UART5TX | UDMA_PRI_SELECT、
   UDMA_SIZE_8 | UDMA_SRC_INC_8 |
   UDMA_DST_INC_NONE |
   UDMA_ARB_1);

   //
   //设置 uDMA UART TX 通道的传输参数。  这将会
   //配置传输源和目的以及传输大小。
   //使用基本模式是因为外设正在进行 UDMA 传输
   //请求。  源是 TX 缓冲区、目的是 UART
   //数据寄存器。
   ROM_uDMAChannelTransferSet (UDMA_CH7_UART5TX | UDMA_PRI_SELECT、
   UDMA_MODE_BASIC、
                               G_ui8pMeterTxBuf、
                              (void *)(UART5_BASE + UART_O_DR)、
                              sizeof (g_ui8pMeterTxBuf));

   //现在,UDMA UART TX 和 RX 通道都被引脚以启动 A
   //传输。  一旦启用通道、外设将会启动
   //发出传输请求,数据传输将开始。
   //
   ROM_uDMAChannelEnable (UDMA_CH6_UART5RX);
   ROM_uDMAChannelEnable (UDMA_CH7_UART5TX);

   //
   //启用 UART DMA TX/RX 中断。
   //

   ///ROM_UARTIntEnable (UART0_BASE、UART_INT_DMATX | UART_INT_DMARX);
   ROM_UARTIntEnable (UART5_BASE、UART_INT_DMARX);
   //
   //启用 UART 外设中断。
   //
   ROM_IntEnable (INT_UART5);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为这篇文章将回答您的问题。

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

    尊敬的 Charles:

    我通读了论坛、讨论的是在正常模式下启用 UART3和5。 在我的情况下、UART5的正常模式(基于中断)工作正常、但 DMA 不适用于 UART5。

    希望您能简单介绍一下我需要通过 UDMA_DEMO (使用 UART0)启用它的具体步骤。

    我可以看到 UART5在通道2中(第713页)、我知道这可能会影响优先级、但除此之外、是否需要以不同的方式启用或配置它?  

    如果我们对 DMA 使用1个以上的外设、是否需要采取任何特殊步骤。

    对、如果我错了、我们只需要为 DMA 启用一个基本控制结构和位置、不管使用了什么外设、对吧?

    我们如何使用编码? 使用通道2或3外设的任何示例用法、以及它与使用通道0外设有何不同。

    我认为、阻碍我在 UART5上实施 DMA 的问题与 UART5的关系更大、就像我提到的、这是我第一次尝试使用 DMA、我还没有完全掌握。

    如果您能查看我的代码并查看是否缺少为 UART5启用 DMA 的任何配置步骤、我将不胜感激。

    非常感谢您阅读如此长的帖子、感谢您对像我这样的新手的耐心等待。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我浏览过您的代码、没有发现任何错误、但您只显示部分代码。 需要进一步分析的一点是突发设置。 您已使用 UDMA_ATTR_USEBURST、而仲裁数目仅为1。 这是我看到的与 TivaWare UDMA_DEMO 相比的差异。 我建议您使用与示例相同的配置、只需将 UART0更改为 UART5。 如果您可以使其正常工作、则可以逐渐适应最终的特定设置。

    另请查看 UDMA DMAWAITSTAT 寄存器。 它是否正在等待一个请求?
    查看 UART 模块 UARTDR 寄存器、您是否看到任何错误以及数据是否写入 DR 寄存器? 也请检查其他寄存器。 由于您说没有 DMA 的正常模式正在工作、因此您可以捕获 UART5的寄存器设置并将其与 DMA 代码进行比较。 如果存在任何重大差异、您可以进一步调查。