这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 学习AI8051开发板例程:28AI8051的USB实现U盘

共2条 1/1 1 跳转至

学习AI8051开发板例程:28AI8051的USB实现U盘

高工
2026-02-20 21:16:42     打赏

二:MSC的基本内容

简单来说,MSC(Mass Storage Class,即USB大容量存储设备类)是一个让USB设备能够与计算机等主机设备标准化地传输文件的通用协议。

它的核心思想,就是让一个复杂的USB设备,在主机(比如你的电脑)看来,就像一个可以直接读写的简单“移动硬盘”。这样,你就能通过“拖放”文件的方式,轻松地在设备和电脑之间交换数据了

二:MSC的工作原理

MSC协议的工作原理:一个精密的“三阶段”流程

MSC协议的核心是Bulk-Only Transport (BOT) 传输协议,它将一次完整的读写操作分解为清晰的三步:

命令传输:主机(如电脑)将想要执行的操作(比如“读取数据”)打包成一个“命令块”(Command Block Wrapper,CBW),发送给USB设备。

数据传输:根据命令的要求,数据开始在主机和设备之间流动。如果是“读取”命令,数据就从设备传向主机;如果是“写入”命令,则方向相反。

状态传输:操作完成后,设备会发回一个“状态包”(Command Status Wrapper,CSW),告诉主机刚才的命令执行成功了,还是出错了。

这个过程中,设备通过一对专门用于大量数据传输的“批量端点”(Bulk Endpoints)来高效地完成数据交换。

三:软件代码如下所示:

3.1 检测外部的存储芯片是否可以正常挂载

BOOL flash_check()
{
    BYTE dat1;
    BYTE dat2;
    BYTE dat3;
    
    if (!fFlashOK)
    {
        SPISS = 0;
        shift(SFC_RDJID);
        dat1 = shift(0x00);
        dat2 = shift(0x00);
        dat3 = shift(0x00);
        SPISS = 1;
        
        //C8 40 13 (GD25Q40)
        //EF 30 13 (W25X40)
        //EF 40 13 (W25Q40)

        if (((dat1 == 0xef) && (dat2 == 0x30)) ||
            ((dat1 == 0xef) && (dat2 == 0x40)) ||
            ((dat1 == 0xc8) && (dat2 == 0x40)))
        {
            if (dat3 == 0x11)
                dwMemorySize = 128*1024;        //GD25Q10/W25X10
            else if (dat3 == 0x12)
                dwMemorySize = 256*1024;        //GD25Q20/W25X20
            else if (dat3 == 0x13)
                dwMemorySize = 512*1024;        //GD25Q40/W25X40
            else if (dat3 == 0x14)
                dwMemorySize = 1024*1024;       //GD25Q80/W25X80
            else if (dat3 == 0x18)
                dwMemorySize = 16384*1024;      //GD25Q128/W25X128
    
            wSectorSize = 4*1024;
            dwSectorNumber = dwMemorySize / wSectorSize;
            
            fFlashOK = 1;
        }
        else
        {
            dwMemorySize = 0;
            wSectorSize = 0;
            dwSectorNumber = 0;
        }
    }
    
    return fFlashOK;
}

3.2 读取固定扇区的大小

void flash_readsector(DWORD addr, BYTE *pdat)
{
    WORD size;
    
    if (!flash_check()) return;
    
    while (flash_isbusy());
    
    SPISS = 0;
    shift(SFC_READ);
    shift((BYTE)(addr >> 16));
    shift((BYTE)(addr >> 8));
    shift((BYTE)(addr));
    for (size = wSectorSize; size; size--)
    {
        *pdat++ = shift(0);
    }
    SPISS = 1;
}

3.3 写入固定扇区的大小

void flash_writesector(DWORD addr, BYTE *pdat)
{
    WORD size;
    
    if (!flash_check()) return;
    
    flash_write_enable();

    SPISS = 0;
    shift(SFC_SECTORER);
    shift((BYTE)(addr >> 16));
    shift((BYTE)(addr >> 8));
    shift((BYTE)(addr));
    SPISS = 1;
    
    size = wSectorSize; 
    while (size)
    {
        flash_write_enable();
    
        SPISS = 0;
        shift(SFC_PAGEPROG);
        shift((BYTE)(addr >> 16));
        shift((BYTE)(addr >> 8));
        shift((BYTE)(addr));
        while (size--)
        {
            shift(*pdat++);
            addr++;
            
            if ((BYTE)(addr) == 0x00)
                break;
        }
        SPISS = 1;
    }
}





关键词: AI8051     MSC    

专家
2026-02-21 07:57:07     打赏
2楼

谢谢楼主分享


共2条 1/1 1 跳转至

回复

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