找回密码
 立即注册

微信扫码登录

查看: 18|回复: 1

8208如何同时打开UART RX DMA溢出和UART_RXDONE中断

[复制链接]

4

主题

1

回帖

42

积分

英勇黄铜

积分
42
发表于 前天 15:31 | 显示全部楼层 |阅读模式 来自 广东深圳
本帖最后由 we_1195536316 于 2025-7-2 15:34 编辑

最近在做一个无线串口透传软件,为了实现低波特率不间断传输的功能,我需要当串口接收数据达到56字节(无线打包长度)时启动无线传输,并且串口继续接收后面的数据,当串口接收超时或数据长度刚好整除56时再次启动无线传输直到串口不再有数据为止。我软件里面同时打开了UART_RXDMA_IRQ和UART_RXDONE_IRQ中断,但是中断貌似不按预期发生,总是同时发生,我自己根据极为有限的资料发现了几个嫌疑点,根据DMA初始化函数的描述:

/**
* @brief     Receive an amount of data in DMA mode.
* @param[in] RecvAddr - Pointer to data buffer, it must be 4-bytes aligned.
* @param[in] RecvBufLen - Length of DMA in bytes, it must be multiple of 16,the maximum value can be up to 4079,
*                         RecvBufLen contains the first four bytes to indicate the received length,so uart packet length needs to be no larger than (recBuffLen - 4).
* @return    none
* @note      -# If the dma receive length reaches the set length, the uart is still receiving data, no rxtimeout is generated,
*               the dma will continue to receive, but no buff overflow occurs, and the loopback receive overwrites the received data.
*/

void uart_recbuff_init(unsigned char *RecvAddr, unsigned short RecvBufLen)

可知参数RecvBufLen必须是16的倍数,而我需要的设置值是56并非16倍数,这个算一个问题。另外上面的描述最后一行还提到当dma接收数据超过设置长度不会发生buff溢出事件只会继续覆盖最前面的数据,这算是我发现的第二个问题。不知道我理解的对不对,另外是否有高人有办法实现我的功能需求。
以下是我UART DMA的初始化代码:

void uart_dma_init(void)
{
        static const uint32_t Baudrate_tab[] = {1200,2400,4800,9600,19200,38400,57600,115200,230400,460800};
        static const UART_ParityTypeDef Parity_tab[] = {PARITY_NONE,PARITY_EVEN,PARITY_ODD,PARITY_NONE,PARITY_EVEN};
        static const UART_StopBitTypeDef StopBit_tab[] = {STOP_BIT_ONE,STOP_BIT_ONE,STOP_BIT_ONE_DOT_FIVE,STOP_BIT_TWO};
        sleep_ms(2000);  //leave enough time for SWS_reset when power on

        gpio_set_func(RS485_T1R0,AS_GPIO);
        gpio_set_output_en(RS485_T1R0, 1);                 //enable output
        gpio_set_input_en(RS485_T1R0,0);                        //disable input
        gpio_write(RS485_T1R0, 0);                      //SET RS485 RX
        //note: dma addr must be set first before any other uart initialization! (confirmed by sihui)
        uart_recbuff_init( (unsigned char *)rec_uart, 56);

        #if( UART_WIRE_MODE == UART_1WIRE_MODE)
        uart_set_rtx_pin(UART_RTX_PIN);// the status of rtx line will be rx by default,if there is a send-action,the status of rtx-line will changed to tx,and changed to rx immediately if send over.
        uart_rtx_en();
        #elif(( UART_WIRE_MODE == UART_2WIRE_MODE))
        uart_gpio_set(UART_TX_PIN, UART_RX_PIN);// uart tx/rx pin set
        #endif

        uart_reset();  //uart module power-on again.

        if (ConfigIfo.UartBaudRate>9 || ConfigIfo.UartParity>4 || ConfigIfo.UartStopBits>3) {
                ConfigIfo.UartBaudRate = 7;ConfigIfo.UartParity = 0;ConfigIfo.UartStopBits = 1;
        }
        //baud rate: 115200
        uart_init_baudrate(Baudrate_tab[ConfigIfo.UartBaudRate],CLOCK_SYS_CLOCK_HZ,Parity_tab[ConfigIfo.UartParity], StopBit_tab[ConfigIfo.UartStopBits]);

        uart_dma_enable(1, 1);         //uart data in hardware buffer moved by dma, so we need enable them first

        uart_rxdone_irq_en();
        irq_enable_type(FLD_IRQ_DMA_EN);// uart_rx use dma_rx irq
        dma_chn_irq_enable(FLD_DMA_CHN_UART_RX, 1);//uart Rx dma irq enable

        uart_mask_tx_done_irq_enable();

        uart_mask_error_irq_enable();// open uart_error_mask,when stop bit error or parity error,it will enter error_interrupt.
        irq_enable_type(FLD_IRQ_UART_EN);// uart_tx use uart_txdone irq
        irq_enable();

        #if( FLOW_CTR ==  USE_CTS )
        uart_set_cts(1, STOP_VOLT, UART_CTS_PIN);
        #elif( FLOW_CTR ==   USE_RTS )
        uart_set_rts(1, RTS_MODE, RTS_THRESH, RTS_INVERT,UART_RTS_PIN);
        #endif
}

0

主题

4

回帖

38

积分

英勇黄铜

积分
38
发表于 昨天 10:55 | 显示全部楼层 来自 上海
本帖最后由 TL_CC 于 2025-7-3 11:07 编辑

你注意的这问题是对的,你可以尝试以下修改:
1. 接收串口数据的buff1长度需满足16的整数倍,具体长度可参考你每次串口传输数据的最大长度,请注意每笔串口数据的格式是: length(4byte)+data(n byte)。
2. 每次接收到串口数据后要及时进行处理,防止被下一笔数据覆盖,建议使用fifo对串口数据进行缓存。
3. 另外使用一个用于无线收发的buff2(该buff2长度可自定义),用于读取FIFO里的串口数据,当buff2中数据长度满足条件后你就可以执行想要的操作了。
希望能够帮助到你。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Telink forum ( 沪ICP备17008231号-1 )

GMT+8, 2025-7-4 00:37 , Processed in 0.092359 second(s), 18 queries .

Powered by Telink 隐私政策

泰凌微电子版权所有 © 。保留所有权利。 2024

快速回复 返回顶部 返回列表