关于TM4C123BE6P芯片UART0的uDMA接收不成功问题

2019-07-24 16:32发布

本帖最后由 pinda_ 于 2015-10-24 17:04 编辑

问题分析:      当前,我先使用FIFO完成了UART0的接收与发送配置,现在,我需要将uDMA加入UART0中。根据例程,我开始尝试:第一步 - 配置uDMA时钟使能           SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);第二步 - 在UART0的配置中,将UART0_TX与UART0_RX加入uDMA中           UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);第三步 - 使能uDMA控制器与指定控制列表地址(用户自定义值为Udma_Control_Table)          uDMAEnable();          uDMAControlBaseSet(Udma_Control_Table);ps: 这里,我暂时不需要uDMA错误中断配置,所以,没有进行配置。第四步 - 定义主发送缓冲区(Udma_Uart0_Xmit_Buf)和主接收缓冲区与备用接收缓冲区(Udma_Uart0_Recv_Buf_A,Udma_Uart0_Recv_Buf_B)          uchar Udma_Uart0_Xmit_Buf[256] = {0x11};          uchar Udma_Uart0_Recv_Buf_A[256] = {0x22};          uchar Udma_Uart0_Recv_Buf_B[256] = {0x33};第五步 - 配置三个通道,两个采用接收通道的控制参数(PINGPONG模式),一个发送通道的控制参数(BASIC模式);同时,配置他们的通道属性:         // 接收通道         uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,                                                         UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |                                                         UDMA_ARB_8);          uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT,                                                          UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |                                                          UDMA_ARB_8);         uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,                                                                  UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |                                                                  UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);         uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0RX,                                                                 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |                                                                 UDMA_ATTR_HIGH_PRIORITY);        // 发送通道        uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,                                                       UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |                                                       UDMA_ARB_8);       uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,                                                                UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |                                                               UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);      uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX,                                                               UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);问题一:这里,有一点不明白,uDMAChannelControlSet库函数中的仲裁大小与UART0中的FIFO深度需要匹配,但是,在UART0中基数为16,假设我设置如下:    UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);那触发点不是8个字节吗?同理,在uDMA中的仲裁大小不是也应该设置UDMA_ARB_8(我认为表示的是8个数目),而TI例程中用UDMA_ARB_4,不是很理解,帮忙解释下?
第六步 - 调用uDMAChannelTransferSet和uDMAChannelEnable函数发送数据             uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,                                                              UDMA_MODE_BASIC,                                                              Udma_Uart0_Xmit_Buf, (void *)(UART0_BASE + UART_O_DR),                                                              sizeof(Udma_Uart0_Xmit_Buf));             uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
以上操作步骤都实验完成。
问题二:但是,我现在想用uDMA接收数据。上位机通过串口TTL电平发送100个数据下来,进入我的UART0中断Uart0_IntHandle,但是,uDMAChannelModeGet函数在UART0中断获取到的值一直为3,也就是PINGPONG模式,并没有得到例程中的0(STOP),也就是接收一直不完成?不明白。问题三:对于uDMAControlBaseSet函数,其中的地址是不是只是充当uDMA的临时寄存器,该值的大小,由发送与接收通道控制结构体大小有关系?希望给予下回答,谢谢;
以下是中断函数代码,对于例程中的中断函数,采用回环控制,但是,数据接收只是单纯的uDMAChannelTransferSet,并没有配置使能接收通道uDMAChannelEnable(UDMA_CHANNEL_UART0RX)语句,这样不是表示该功能是禁止的吗,调用发送好像没有意义,而且这里的发送,我根据源地址与目的地址理解,是将UART0数据寄存器中读取数据,写入我新定义的uDMA接收缓冲地址中,不知道这样理解对吗?
void Uart0_IntHandle(void)
{
    /* 中断状态反馈 */
        uint32 ulIntState;
        uint32 ulModeRx;
        uint32 ulModeTx;

    //! The e ulIntState parameter is the logical OR of any of the following:
        //!
        //! -  UART_INT_OE - Overrun Error interrupt
        //! -  UART_INT_BE - Break Error interrupt
        //! -  UART_INT_PE - Parity Error interrupt
        //! -  UART_INT_FE - Framing Error interrupt
        //! -  UART_INT_RT - Receive Timeout interrupt
        //! -  UART_INT_RX - Receive interrupt
        ulIntState = UARTIntStatus(UART0_BASE, TRUE);

        /* Clear the interrupt flag */
        UARTIntClear(UART0_BASE, ulIntState);
       
        /* Check the DMA control table to see if the ping-pong "A" transfer is
       complete.  The "A" transfer uses receive buffer "A", and the primary
       control structure. */
        ulModeRx = uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
       
        ulModeTx = uDMAChannelModeGet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT);

    /* 检查当前中断状态,做出对应的处理方式 */
        switch (ulIntState)
        {
            case UART_INT_RX:
                {
                    Uart0_Recv_IntHandle();
                }
                break;
            case UART_INT_RT:
                {
                   
                }
                break;
            case UART_INT_OE:
                {
                    
                }
                break;
        case UART_INT_BE:
                {
                       
                }
                break;
        case UART_INT_PE:
                {
                    
                }
                break;
        case UART_INT_FE:
                {
                       
                }
                break;
        default: break;
        }
}

如果有什么相关资料可以参考,希望发份资料看看,争取把uDMA搞完。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
dirtwillfly
1楼-- · 2019-07-24 17:59
@xyz549040622 帮看看这个问题
xyz549040622
2楼-- · 2019-07-24 21:25
你这个问题,我再查查资料,不敢贸然回答,需要实际测试的。如果楼主测试好了,也可以分享下经验。
baimiaocun2015
3楼-- · 2019-07-24 22:38
定义主发送缓冲区(Udma_Uart0_Xmit_Buf)和主接收缓冲区与备用接收缓冲区(Udma_Uart0_Recv_Buf_A,Udma_Uart0_Recv_Buf_B),,这个是很关键。
旧影子
4楼-- · 2019-07-25 02:24
看不懂,给楼主支持下!
米尔豪斯
5楼-- · 2019-07-25 05:13
 精彩回答 2  元偷偷看……
可可球
6楼-- · 2019-07-25 08:47
Ultra DMA的英文拼写为“Ultra Direct Memory Access”,一般简写为UDMA,含义是超直接存储器存取(海量存储接口)

一周热门 更多>