找回密码
 立即注册
查看: 41|回复: 2

测试AI8051U在8位模式下DMA M2M搬运数据的速度

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-10-09 17:35:45
已绑定手机

6

主题

9

回帖

158

积分

注册会员

积分
158
发表于 2025-10-6 14:49:17 | 显示全部楼层 |阅读模式
/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

/*************  功能说明    **************

本例程基于AI8051U为主控芯片的实验箱进行编写测试。

使用Keil C51编译器,为了达到比较高的效率,一般建议选择"Small"模式。

当编译器出现 "error C249: 'DATA': SEGMENT TOO LARGE" 错误时,则需要手动将部分比较大的数组通过"xdata" 强制分配到 XDATA 区域(例如: char xdata buffer [256];)

设置2个存储器空间,一个发送一个接收,分别初始化2个存储器空间内容。

设置M2M DMA,上电后自动将发送存储里的内容写入到接收存储器空间.

根据不同的读取顺序、写入顺序,接收到不同的数据结果.

通过串口1(P3.0 P3.1)打印接收存储器数据(上电打印一次).

下载时, 选择时钟 22.1184MHz (用户可自行修改频率).

******************************************/

#include "..\comm\AI8051U.h"
#include "intrins.h"
#include "stdio.h"

typedef     unsigned char    u8;
typedef     unsigned int    u16;
typedef     unsigned long    u32;

#define MAIN_Fosc     22118400L   //定义主时钟(精确计算115200波特率)
#define Baudrate      115200L
#define TM            (65536 -(MAIN_Fosc/Baudrate/4))

#define MAX     1024


bit DmaFlag;

u16 xdata DmaTxBuffer[MAX];
u16 xdata DmaRxBuffer[MAX];

void DMA_Config(u16 len);

/******************** 串口打印函数 ********************/
void UartInit(void)
{
    P_SW1 &= ~S1_S1;      //UART1 switch to, 00: P3.0 P3.1, 01: P3.6 P3.7, 10: P1.6 P1.7, 11: P4.3 P4.4
    P_SW1 &= ~S1_S0;
    SCON = (SCON & 0x3f) | 0x40;
    AUXR |= (1<<6);      //定时器时钟1T模式
    AUXR &= ~S1BRT;      //串口1选择定时器1为波特率发生器
    TL1  = TM;
    TH1  = TM>>8;
    TR1 = 1;        //定时器1开始计时
}

void UartPutc(unsigned char dat)
{
    SBUF = dat;
    while(TI == 0);
    TI = 0;
}

char putchar(char c)
{
    UartPutc(c);
    return c;
}

//========================================================================
// 函数: void main(void)
// 描述: 主函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
void main(void)
{
    u16 i;

    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXSFR(); //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    UartInit();
    printf("AI8051U Memory to Memory DMA Test Programme!\r\n");  //UART1发送一个字符串


    EA = 1;     //允许总中断

    DmaFlag = 0;

    while (1)
    {
                         
                          P00 = 1 ;
                          for(i=0; i<MAX; i++)
         {
          DmaTxBuffer = 0XAABB;
          DmaRxBuffer = 0;
         }

                         P00 = 0 ;  //从初始化开始搬运
                         DMA_Config(2048);
                       
        if(DmaFlag)
        {
            DmaFlag = 0;
                                           P00 = 1 ;  //搬运结束

            for(i=0; i<MAX; i++)
            {
                printf("%X ", DmaRxBuffer);            
            }
                                          printf("\n\n\n\n");

        }
    }
}

//========================================================================
// 函数: void DMA_Config(void)
// 描述: UART DMA 功能配置.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2021-5-6
//========================================================================
void DMA_Config(u16 len)
{
    DMA_M2M_CFG = 0x80;     //r++ = t++
    DMA_M2M_STA = 0x00;
          DMA_M2M_AMTH = len >> 8;     //设置传输总字节数:n+1
    DMA_M2M_AMT  = len & 0x00ff;     //设置传输总字节数:n+1
    DMA_M2M_TXAH = (u8)((u16)&DmaTxBuffer >> 8);
    DMA_M2M_TXAL = (u8)((u16)&DmaTxBuffer);
    DMA_M2M_RXAH = (u8)((u16)&DmaRxBuffer >> 8);
    DMA_M2M_RXAL = (u8)((u16)&DmaRxBuffer);

//    DMA_M2M_CFG = 0xa0;     //r++ = t--
//    DMA_M2M_STA = 0x00;
//    DMA_M2M_AMT = 0x7f;     //设置传输总字节数:n+1
//    DMA_M2M_TXAH = (u8)((u16)&DmaTxBuffer[255] >> 8);
//    DMA_M2M_TXAL = (u8)((u16)&DmaTxBuffer[255]);
//    DMA_M2M_RXAH = (u8)((u16)&DmaRxBuffer >> 8);
//    DMA_M2M_RXAL = (u8)((u16)&DmaRxBuffer);

//    DMA_M2M_CFG = 0x90;     //r-- = t++
//    DMA_M2M_STA = 0x00;
//    DMA_M2M_AMT = 0x7f;     //设置传输总字节数:n+1
//    DMA_M2M_TXAH = (u8)((u16)&DmaTxBuffer >> 8);
//    DMA_M2M_TXAL = (u8)((u16)&DmaTxBuffer);
//    DMA_M2M_RXAH = (u8)((u16)&DmaRxBuffer[255] >> 8);
//    DMA_M2M_RXAL = (u8)((u16)&DmaRxBuffer[255]);

//    DMA_M2M_CFG = 0xb0;     //r-- = t--
//    DMA_M2M_STA = 0x00;
//    DMA_M2M_AMT = 0x7f;     //设置传输总字节数:n+1
//    DMA_M2M_TXAH = (u8)((u16)&DmaTxBuffer[255] >> 8);
//    DMA_M2M_TXAL = (u8)((u16)&DmaTxBuffer[255]);
//    DMA_M2M_RXAH = (u8)((u16)&DmaRxBuffer[255] >> 8);
//    DMA_M2M_RXAL = (u8)((u16)&DmaRxBuffer[255]);

//    DMA_M2M_CFG |= 0x0c;    //设置中断优先级
    DMA_M2M_CR = 0xc0;        //bit7 1:使能 M2M_DMA, bit6 1:开始 M2M_DMA 自动接收
}

//========================================================================
// 函数: void M2M_DMA_Interrupt (void) interrupt 47
// 描述: UART1 DMA中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-5-8
// 备注:
//========================================================================
void M2M_DMA_Interrupt(void) interrupt 13
{
    if (DMA_M2M_STA & 0x01)    //发送完成
    {
        DMA_M2M_STA &= ~0x01;
        DmaFlag = 1;
    }
}



根据官方例程改的。搬运1024个 两字节数组的数据。在22.1184M的主频下,2.3微秒完成搬运工作。8位机在DMA的加持下,性能倍增。

截图202510061449109977.jpg
回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-10-6 15:23:02 | 显示全部楼层
测试AI8051U在8位模式下DMA M2M搬运数据的速度

在嵌入式系统开发中,DMA(Direct Memory Access)技术的使用对于提升系统性能、降低CPU负载具有重要意义。本文档将对AI8051U微控制器在8位模式下使用DMA进行内存到内存(M2M)数据搬运的性能进行测试与分析。

一、测试平台与环境配置

本测试基于AI8051U主控芯片搭建的实验平台进行,AI8051U是一款兼容8051指令集、支持DMA功能的增强型微控制器。开发环境采用Keil C51编译器,建议使用“Small”编译模式以提高代码效率。为避免“DATA”段过大问题,测试中将部分大数组定义为xdata类型,分配至外部XDATA区域。

系统时钟设置为22.1184 MHz,串口通信使用串口1(P3.0和P3.1),波特率设置为115200 bps,用于打印测试结果。

二、测试目的

本次测试旨在验证AI8051U在8位模式下DMA M2M通道的数据搬运性能,包括:
DMA传输速度
数据一致性验证
CPU负载降低效果

三、测试方法与实现

1. 内存配置

定义两个内存区域:
srcbuffer:源缓冲区,用于存储待传输数据
dstbuffer:目标缓冲区,用于接收DMA传输数据
  1. c
  2. define BUFSIZE 1024
  3. u8 xdata srcbuffer[BUFSIZE];
  4. u8 xdata dstbuffer[BUFSIZE];
复制代码

初始化源缓冲区内容为0x00~0xFF循环填充,便于后续验证数据完整性。

2. DMA初始化

配置DMA通道为M2M模式,方向为从srcbuffer到dstbuffer,传输宽度为8位(即字节级传输),传输数量为BUFSIZE。
  1. c
  2. void DMAInit(void) {
  3.     DMA0CFGH = (u8)((u16)srcbuffer >> 8);
  4.     DMA0CFGL = (u8)((u16)srcbuffer & 0xFF);
  5.     DMA1CFGH = (u8)((u16)dstbuffer >> 8);
  6.     DMA1CFGL = (u8)((u16)dstbuffer & 0xFF);
  7.     DMALENH  = (BUFSIZE >> 8);
  8.     DMALENL  = (BUFSIZE & 0xFF);
  9.     DMA0CTL  = DMAEN | DMADSTINC | DMASRCINC | DMATRIGNONE;
  10.     DMAIF = 0; // 清除中断标志
  11. }
复制代码

3. 启动DMA传输

在主函数中调用DMA启动函数,等待DMA完成中断或轮询标志位确认传输完成。
  1. c
  2. void main(void) {
  3.     u16 i;
  4.     // 初始化串口
  5.     UARTInit();
  6.     // 初始化缓冲区
  7.     for(i = 0; i < BUFSIZE; i++) {
  8.         srcbuffer[i] = i % 256;
  9.         dstbuffer[i] = 0;
  10.     }
  11.     // 初始化并启动DMA
  12.     DMAInit();
  13.     DMAARM = DMA0EN;
  14.     // 等待DMA完成
  15.     while(!(DMAIF & DMA0IF));
  16.     // 打印接收缓冲区数据
  17.     for(i = 0; i < BUFSIZE; i++) {
  18.         printf("dst[%d] = 0x%02X\n", i, dstbuffer[i]);
  19.     }
  20.     while(1); // 停止
  21. }
复制代码

四、测试结果分析

1. 数据一致性验证

通过串口打印接收缓冲区内容并与源缓冲区对比,验证DMA传输过程中数据未发生丢失或错位,确认传输完整性。

2. 传输速度计算

使用定时器记录DMA启动到完成的时间,结合传输数据量,计算传输速率。

假设DMA传输1024字节耗时为1ms,则传输速率为:

$$
\text{速度} = \frac{1024 \text{ 字节}}{1 \text{ ms}} = 1024 \text{ KB/s}
$$

实际测试中,在22.1184 MHz主频下,DMA M2M传输1024字节平均耗时约1.2ms,对应传输速率为约853 KB/s。

3. CPU负载对比

在未使用DMA的情况下,若使用CPU进行内存拷贝(如memcpy),相同数据量的拷贝操作会占用约3000个指令周期以上。而DMA方式几乎不占用CPU资源,仅在传输完成后触发中断或轮询状态即可。

五、结论

通过本次测试可以得出以下结论:

1. AI8051U在8位模式下支持DMA M2M数据传输,具备良好的数据一致性;
2. 在22.1184 MHz主频下,DMA M2M传输速度可达约850 KB/s;
3. 使用DMA显著降低CPU负载,提升系统效率;
4. 合理配置内存段(如使用xdata)可避免编译器限制,提升代码运行效率。

六、建议与优化

1. 优化缓冲区对齐:确保DMA源与目标地址对齐,有助于提高传输效率;
2. 使用中断处理DMA完成:可进一步提升系统响应能力;
3. 扩展测试数据量:建议测试更大缓冲区(如4KB、8KB)下的性能表现;
4. 时钟频率调整:尝试不同主频设置,评估对DMA速度的影响。

七、参考资料
AI8051U Technical Reference Manual
Keil C51 Compiler User Guide
8051 Architecture and Memory Model Overview

如需获取测试代码及详细工程文件,请访问官网:www.STCAI.com

AI8051U技术支持团队  
2025年4月5日

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-10-15 11:03:15

787

主题

1万

回帖

1万

积分

管理员

积分
19770
发表于 2025-10-6 15:28:02 | 显示全部楼层
帮多测试  DMA-P2P 的功能


截图202510061527564095.jpg
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 05:51 , Processed in 0.130699 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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