这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 学习AI8051开发板例程:29AI8051的DMA方式接收串口数据并返回给PC

共2条 1/1 1 跳转至

学习AI8051开发板例程:29AI8051的DMA方式接收串口数据并返回给PC端

高工
2026-02-20 21:44:35   被打赏 50 分(兑奖)     打赏

一:AI8051的DMA基础知识分享:

AI8051的DMA,支持解放 CPU的外设到外设传输(P2P):

目前支持的DMA通道如下所示:

    M2M DMA:XRAM存储器到XRAM存储器的数据读写

    ADC DMA:自动扫描使能的ADC 通道并将转换的ADC 数据自动存储到XRAM中

    SPI DMA:自动将XRAM中的数据和 SPI外设之间进行数据交换

    UR1T_DMA:自动将XRAM中的数据通过串口1发送出去

    UR1RDMA:自动将串口1接收到的数据存储到XRAM中

    自动将XRAM中的数据通过串口2发送出去

    UR2T DMA:自动将串口2接收到的数据存储到XRAM中UR2R DMA:

    UR3T_DMA自动将XRAM中的数据通过串口3发送出去:

    UR3R DMA自动将串口3接收到的数据存储到XRAM中:

    UR4T DMA自动将XRAM中的数据通过串口4发送出去:

    UR4R_DMA:自动将串口4接收到的数据存储到XRAM中

    TFT彩屏DMA:自动将XRAM中的数据和TFT彩屏设备之间进行数据交换

    I2CT_DMA:自动将XRAM中的数据通过I2C接口发送出去

    I2CR_DMA:自动将I2C接收到的数据存储到XRAM中I2ST_DMA:自动将XRAM中的数据通过I2S发送出去

    I2SR_DMA:自动将I2S接收到的数据存储到XRAM中

    QSPI_DMA:自动将XRAM中的数据和QSPI外设之间进行数据交换

    PWMAT_DMA:自动将XRAM中的数据通过PWMA接口发送出去

    PWMAR DMA:自动将 PWMA接收到的数据存储到XRAM中

    P2P:自动将源外设接收到的数据透传到目标外设(支持两组P2P)

注意:每次DMA数据传输最大数据量为65535字节,即将AMT 设置为OxFFFE;当将AMT 设置为OxFFFF时,则DMA为无限循环模式。(存储器到存储器的DMA没有无限循环模式)

二:软件代码配置如下所示:

2.1 串口DMA初始化:

void DMA_Config(void)
{
    DMA_UR1T_CFG = 0x00;        //bit7 1:Enable Interrupt
    DMA_UR1T_STA = 0x00;
    DMA_UR1T_AMT = 0xff;        //设置传输总字节数(低8位):n+1
    DMA_UR1T_AMTH = 0x01;       //设置传输总字节数(高8位):n+1
    DMA_UR1T_TXAH = (u8)((u16)&DmaBuffer >> 8);
    DMA_UR1T_TXAL = (u8)((u16)&DmaBuffer);
    DMA_UR1T_CR = 0x80;         //bit7 1:使能 UART1_DMA, bit6 1:开始 UART1_DMA 自动发送

    DMA_UR1R_CFG = 0x00;        //bit7 1:Enable Interrupt
    DMA_UR1R_STA = 0x00;
    DMA_UR1R_AMT = 0xff;        //设置传输总字节数(低8位):n+1
    DMA_UR1R_AMTH = 0x03;       //设置传输总字节数(高8位):n+1
    DMA_UR1R_RXAH = (u8)((u16)&DmaBuffer >> 8);
    DMA_UR1R_RXAL = (u8)((u16)&DmaBuffer);
    DMA_UR1R_CR = 0xa1;         //bit7 1:使能 UART1_DMA, bit5 1:开始 UART1_DMA 自动接收, bit0 1:清除 FIFO
}

2.2 串口中断处理部分:

void UART1_int (void) interrupt 4
{
    if(UR1TOSR & 0x01)
    {
        B_RX1_TimeOut = 1;
        UR1TOSR = 0x80; //设置 RTOCF 清除超时标志位 TOIF
    }
}

2.3 串口DMA中断函数如下所示:

void UART1_DMA_Interrupt(void) interrupt 13
{
    if (DMA_UR1T_STA & 0x01)    //发送完成
    {
        DMA_UR1T_STA &= ~0x01;
        DmaTxFlag = 1;
    }
    if (DMA_UR1T_STA & 0x04)    //数据覆盖
    {
        DMA_UR1T_STA &= ~0x04;
    }
    
    if (DMA_UR1R_STA & 0x01)    //接收完成
    {
        DMA_UR1R_STA &= ~0x01;
        DmaRxFlag = 1;
    }
    if (DMA_UR1R_STA & 0x02)    //数据丢弃
    {
        DMA_UR1R_STA &= ~0x02;
    }
}

2.4 数据回传函数如下所示:

        if(B_RX1_TimeOut)
        {
            B_RX1_TimeOut = 0;

            i = ((u16)DMA_UR1R_DONEH << 8) + DMA_UR1R_DONE;
            i--;
            DMA_UR1T_AMT = (u8)i;       //设置传输总字节数(低8位):i+1
            DMA_UR1T_AMTH = (u8)(i>>8); //设置传输总字节数(高8位):i+1

            //关闭接收DMA,下次接收的数据重新存放在起始地址位置,否则下次接收数据继续往后面存放。同时会清除 DMA_UR1R_DONE
            DMA_UR1R_CR = 0;
//            printf("cnt=%u\r\n",i);
            DMA_UR1T_CR = 0xc0;            //bit7 1:使能 UART1_DMA, bit6 1:开始 UART1_DMA 自动发送
            DMA_UR1R_CR = 0xa1;            //bit7 1:使能 UART1_DMA, bit5 1:开始 UART1_DMA 自动接收, bit0 1:清除 FIFO
        }

三:测试图如下所示:

29-1.png

ai29-2.png





关键词: AI8051     DMA    

院士
2026-02-21 09:50:50     打赏
2楼

这是直接寄存器配置啊


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]