牛卧堂MCU技术交流

标题: 请问关于M467的串口DMA超时判断问题 [打印本页]

作者: 匿名    时间: 2023-11-17 16:28
标题: 请问关于M467的串口DMA超时判断问题
请问关于M467的串口DMA超时判断问题,现在遇到的一个问题是:

MCU通过RS422连接了一个对方设备,23400bps,100HZz帧率,使用DMA超时判断,发现重新上电对MCU和对方设备,MCU无法实现TIMEOUT响应,而每次通过下载器下载更新程序,却可以实现串口DMA接收。

请问这个问题大概出在哪里?

作者: 匿名    时间: 2023-11-17 20:52
配置的过程是这样的:

过程如下:

#define UART9_RX_DMA_CH                     (9)
#define UART9_PDMA_OPENED_CH_RX           (1 << UART9_RX_DMA_CH)

    UART9_Init(230400);
    set_flag(flag_UART9_RX_end, DISABLE);
    SYS_ResetModule(PDMA0_RST);
    UART_PDMA_ENABLE(UART9, UART_INTEN_RXPDMAEN_Msk);
    PDMA_Open(PDMA0, UART9_PDMA_OPENED_CH_RX);

    PDMA_SetTransferCnt(PDMA0,  UART9_RX_DMA_CH, PDMA_WIDTH_8, RX_size9);
    PDMA_SetTransferAddr(PDMA0, UART9_RX_DMA_CH, UART9_BASE, PDMA_SAR_FIX, ((uint32_t) (&UART9_RXBuffer[0])), PDMA_DAR_INC);
    PDMA_SetTransferMode(PDMA0, UART9_RX_DMA_CH, PDMA_UART9_RX, 0, 0);
    PDMA_SetBurstType(PDMA0, UART9_RX_DMA_CH, PDMA_REQ_SINGLE, 0);
    PDMA_DisableInt(PDMA0, UART9_RX_DMA_CH, PDMA_INT_TEMPTY );
    PDMA_EnableInt(PDMA0, UART9_RX_DMA_CH, PDMA_INT_TRANS_DONE);
    PDMA_EnableInt(PDMA0, UART9_RX_DMA_CH, PDMA_INT_TIMEOUT);
    PDMA_SetTimeOut(PDMA0, UART9_RX_DMA_CH, OPEN, pdmat9);
    NVIC_EnableIRQ(PDMA0_IRQn);


void PDMA0_IRQHandler(void)
{
    uint32_t status = PDMA_GET_INT_STATUS(PDMA0);

。。。。。。。。。。。。。。。部分省略

        if (PDMA_GET_TD_STS(PDMA0) & UART9_PDMA_OPENED_CH_RX)//UART9-done-RX
        {
            printf("\r\n uart9-done \r\n");
            set_flag(flag_UART9_RX_end, ENABLE);
            PDMA_CLR_TD_FLAG(PDMA0, UART9_PDMA_OPENED_CH_RX);
        }

。。。。。。。。。。。。。。。部分省略
    else if (status & (PDMA_INTSTS_REQTOF9_Msk))                        //UART9-timeout
    {
        printf("\r\n uart9-timerout \r\n");
        PDMA_SetTimeOut(PDMA0, UART9_RX_DMA_CH, DISABLE, 0);
        PDMA_CLR_TMOUT_FLAG(PDMA0, UART9_RX_DMA_CH);
        PDMA_SetTimeOut(PDMA0, UART9_RX_DMA_CH, ENABLE, pdmat9);               
        set_flag(flag_UART9_RX_end, ENABLE);
    }
}



while(1)
{
    if (is_flag_set(flag_UART9_RX_end))
    {
        set_flag(flag_UART9_RX_end, DISABLE);
        reset_buffer(UART9_RXBuffer, 0x00, RX_size9);


    PDMA_SetTransferCnt (PDMA0,UART9_RX_DMA_CH, PDMA_WIDTH_8, RX_size9);
    PDMA_SetTransferAddr(PDMA0,UART9_RX_DMA_CH, UART9_BASE, PDMA_SAR_FIX, ((uint32_t) (&UART9_RXBuffer[0])), PDMA_DAR_INC);       
    PDMA_SetTransferMode(PDMA0,UART9_RX_DMA_CH, PDMA_UART9_RX, FALSE, 0);
    }
}



作者: 匿名    时间: 2023-11-17 20:59
操作过程,是这样的,对方设备上电之后,只有单片机经过重启,才可以接受到TIME-OUT触发;
当对方设备特意断电,重新上电,M467一直带电,无法收到TIME-OUT触发;

也就是说,只有单片机必须经过手动复位之后,才可以接受到TIME-OUT循环触发。

恳请大家给予指点!
谢谢!
作者: Angus    时间: 2023-11-21 10:41
UART口对方重新上电,UART总线上数据时序就不对了,UART会出现帧错——就是找不到字节开头,显然后续数据都错了,这时PDMA 会停止传输。
重新启动传输的办法是,通过RXRST 把接收 FIFO 中出错的数据全清除,就可以了。

这么复杂的问题,建议找新唐代理商的FAE。他们会给你很多帮助。
作者: 匿名    时间: 2023-11-21 11:21
感谢大力支持!最终的问题就是这样解决的!
谢谢!
通过RXRST 把接收 FIFO 中出错的数据全清除,就可以了。




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2