请选择 进入手机版 | 继续访问电脑版

安富莱电子论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 272|回复: 9
收起左侧

[FatFs] 用stm32F4的sdio驱动emmc

[复制链接]

3

主题

16

帖子

22

积分

新手上路

积分
22
发表于 2019-2-14 17:06:19 | 显示全部楼层 |阅读模式
本帖最后由 孤独的行程者 于 2019-2-15 16:45 编辑

请问有哪个大神用stm32玩过emmc的,可以一起分享下资料。
我参考网上的资料,按照这样顺序下发指令:CMD0 -> CMD1 -> CM2 -> CMD3 -> CMD9 -> 获取卡的信息->CMD7 -> CMD8(eMMC需要获得两次卡的信息,这是第二次)(读取ExtCSD寄存器信息)
现在我获取容量错误的,但是可以用扇区进行读写,跑Fatfs文件系统就不行。

JDEDC JESD84-B451中文.pdf

5.25 MB, 下载次数: 15

这是emmc参考资料

sdio_sdcard.c

65.98 KB, 下载次数: 14

这是我写的程序,请大神看看是什么问题

sdio_sdcard.h

23.48 KB, 下载次数: 10

SdioEmmcDrive.c

70.86 KB, 下载次数: 10

这是阿莫论坛的参考资料

SdioEmmcDrive.h

23.96 KB, 下载次数: 10

回复

使用道具 举报

5677

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

积分
45712
QQ
发表于 2019-2-14 17:21:55 | 显示全部楼层
这个有研究价值。

MicroPython要发布一个带eMMC的套件,到时可以看看他们的驱动。

一般来说,只要你实现了读写函数,添加到FatFS的接口文件diskio.C就行。
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

3

主题

16

帖子

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-14 17:29:33 | 显示全部楼层
现在是获取emmc容量的计算错误,进行扇区读写是没问题的,但不知道是不是所有扇区读写都没问题,我只是简单测试了几个扇区读写。
回复

使用道具 举报

5677

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

积分
45712
QQ
发表于 2019-2-15 00:09:11 | 显示全部楼层
孤独的行程者 发表于 2019-2-14 17:29
现在是获取emmc容量的计算错误,进行扇区读写是没问题的,但不知道是不是所有扇区读写都没问题,我只是简单 ...

amobbs上有位网友开源的,你参考下

https://www.amobbs.com/forum.php?mod=viewthread&tid=5577382
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

1

主题

457

帖子

459

积分

高级会员

积分
459
发表于 2019-2-15 08:52:29 | 显示全部楼层
嗯 阿莫上有人写了程序,还有人画了板子…
大于4.0版本的emmc估计32处理器玩不了
淘宝上还有emmc模块底板PCB,焊接好的成品模块都有卖的
玩的人还不少,估计都是冲着大容量自带磨损均衡等管理功能去的吧
选用时要注意工业等级,品质按常规理解, 三桑>透希巴>三低,坑屎顿
如果不考虑工业等级的话,还不如在板子上直接焊接一个sd卡上去,还省一个sd卡座子!
回复

使用道具 举报

3

主题

16

帖子

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:44:31 | 显示全部楼层
本帖最后由 孤独的行程者 于 2019-2-15 16:49 编辑

我已上传阿莫论坛的资料,你可以看下。我就是参考阿莫论坛的程序写的,不过有部分看不太懂,部分是照搬,现在就卡在那里。我是想知道那个论坛里有个人也参考程序能执行,但是我没帐号下载不了
QQ截图20190215164048.png
回复

使用道具 举报

3

主题

16

帖子

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:48:04 | 显示全部楼层
leiyitan 发表于 2019-2-15 08:52
嗯 阿莫上有人写了程序,还有人画了板子…
大于4.0版本的emmc估计32处理器玩不了
淘宝上还有emmc模块底板 ...

我是买了NanoPi M4配用的emmc模块,尝试用stm32f4看看能不能用fatfs文件系统进行读写文件,想代替nandflash存储大量文件
回复

使用道具 举报

3

主题

16

帖子

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:50:59 | 显示全部楼层
本帖最后由 孤独的行程者 于 2019-2-15 16:54 编辑

现在就卡死在这部分

//得到卡信息
//cardinfo:卡信息存储区
//返回值:错误状态
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
{
        SD_Error errorstatus=SD_OK;
        u8 tmp=0;          
        cardinfo->CardType=(u8)CardType;                                 //卡类型
        cardinfo->RCA=(u16)RCA;                                                        //卡RCA值
        tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
        cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6;                //CSD结构
        cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2;        //2.0协议还没定义这部分(为保留),应该是后续协议定义的
        cardinfo->SD_csd.Reserved1=tmp&0x03;                        //2个保留位  
        tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);                        //第1个字节
        cardinfo->SD_csd.TAAC=tmp;                                                   //数据读时间1
        tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);                          //第2个字节
        cardinfo->SD_csd.NSAC=tmp;                                                  //数据读时间2
        tmp=(u8)(CSD_Tab[0]&0x000000FF);                                //第3个字节
        cardinfo->SD_csd.MaxBusClkFrec=tmp;                                  //传输速度          
        tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24);                        //第4个字节
        cardinfo->SD_csd.CardComdClasses=tmp<<4;            //卡指令类高四位
        tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16);                         //第5个字节
        cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;//卡指令类低四位
        cardinfo->SD_csd.RdBlockLen=tmp&0x0F;                    //最大读取数据长度
        tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8);                        //第6个字节
        cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7;        //允许分块读
        cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6;        //写块错位
        cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5;        //读块错位
        cardinfo->SD_csd.DSRImpl=(tmp&0x10)>>4;
        cardinfo->SD_csd.Reserved2=0;                                         //保留
//         if((CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1)||(CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)||(SDIO_MULTIMEDIA_CARD==CardType))//标准1.1/2.0卡/MMC卡
//        {
                cardinfo->SD_csd.DeviceSize=(tmp&0x03)<<10;        //C_SIZE(12位)
                 tmp=(u8)(CSD_Tab[1]&0x000000FF);                         //第7个字节       
                cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
                tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);                //第8个字节       
                cardinfo->SD_csd.DeviceSize|=(tmp&0xC0)>>6;
                cardinfo->SD_csd.MaxRdCurrentVDDMin=(tmp&0x38)>>3;
                cardinfo->SD_csd.MaxRdCurrentVDDMax=(tmp&0x07);
                tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);                //第9个字节       
                cardinfo->SD_csd.MaxWrCurrentVDDMin=(tmp&0xE0)>>5;
                cardinfo->SD_csd.MaxWrCurrentVDDMax=(tmp&0x1C)>>2;
                cardinfo->SD_csd.DeviceSizeMul=(tmp&0x03)<<1;//C_SIZE_MULT
                tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);                  //第10个字节       
                cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
//                 cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);//计算卡容量
//                cardinfo->CardCapacity*=(1<<(cardinfo->SD_csd.DeviceSizeMul+2));
//                cardinfo->CardBlockSize=1<<(cardinfo->SD_csd.RdBlockLen);//块大小
//                cardinfo->CardCapacity*=cardinfo->CardBlockSize;
               
                cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen);

//这部分就是计算容量的
                cardinfo->CardCapacity = (uint64_t)((uint64_t)(cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[3] << 24 | cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[2] << 16 |
                cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[1] << 8 | cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[0]) * cardinfo->CardBlockSize);


//        }else if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)        //高容量卡
//        {
//                 tmp=(u8)(CSD_Tab[1]&0x000000FF);                 //第7个字节       
//                cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;//C_SIZE
//                 tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);         //第8个字节       
//                 cardinfo->SD_csd.DeviceSize|=(tmp<<8);
//                 tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);        //第9个字节       
//                 cardinfo->SD_csd.DeviceSize|=(tmp);
//                 tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);         //第10个字节       
//                 cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;//计算卡容量
//                cardinfo->CardBlockSize=512;                         //块大小固定为512字节
//        }          
        cardinfo->SD_csd.EraseGrSize=(tmp&0x40)>>6;
        cardinfo->SD_csd.EraseGrMul=(tmp&0x3F)<<1;          
        tmp=(u8)(CSD_Tab[2]&0x000000FF);                        //第11个字节       
        cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
        cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
        tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24);                //第12个字节       
        cardinfo->SD_csd.WrProtectGrEnable=(tmp&0x80)>>7;
        cardinfo->SD_csd.ManDeflECC=(tmp&0x60)>>5;
        cardinfo->SD_csd.WrSpeedFact=(tmp&0x1C)>>2;
        cardinfo->SD_csd.MaxWrBlockLen=(tmp&0x03)<<2;         
        tmp=(u8)((CSD_Tab[3]&0x00FF0000)>>16);                //第13个字节
        cardinfo->SD_csd.MaxWrBlockLen|=(tmp&0xC0)>>6;
        cardinfo->SD_csd.WriteBlockPaPartial=(tmp&0x20)>>5;
        cardinfo->SD_csd.Reserved3=0;
        cardinfo->SD_csd.ContentProtectAppli=(tmp&0x01);  
        tmp=(u8)((CSD_Tab[3]&0x0000FF00)>>8);                //第14个字节
        cardinfo->SD_csd.FileFormatGrouop=(tmp&0x80)>>7;
        cardinfo->SD_csd.CopyFlag=(tmp&0x40)>>6;
        cardinfo->SD_csd.PermWrProtect=(tmp&0x20)>>5;
        cardinfo->SD_csd.TempWrProtect=(tmp&0x10)>>4;
        cardinfo->SD_csd.FileFormat=(tmp&0x0C)>>2;
        cardinfo->SD_csd.ECC=(tmp&0x03);  
        tmp=(u8)(CSD_Tab[3]&0x000000FF);                        //第15个字节
        cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
        cardinfo->SD_csd.Reserved4=1;                 
        tmp=(u8)((CID_Tab[0]&0xFF000000)>>24);                //第0个字节
        cardinfo->SD_cid.ManufacturerID=tmp;                    
        tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16);                //第1个字节
        cardinfo->SD_cid.OEM_AppliID=tmp<<8;          
        tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8);                //第2个字节
        cardinfo->SD_cid.OEM_AppliID|=tmp;            
        tmp=(u8)(CID_Tab[0]&0x000000FF);                        //第3个字节       
        cardinfo->SD_cid.ProdName1=tmp<<24;                                  
        tmp=(u8)((CID_Tab[1]&0xFF000000)>>24);                 //第4个字节
        cardinfo->SD_cid.ProdName1|=tmp<<16;          
        tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16);                   //第5个字节
        cardinfo->SD_cid.ProdName1|=tmp<<8;                 
        tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8);                //第6个字节
        cardinfo->SD_cid.ProdName1|=tmp;                  
        tmp=(u8)(CID_Tab[1]&0x000000FF);                          //第7个字节
        cardinfo->SD_cid.ProdName2=tmp;                          
        tmp=(u8)((CID_Tab[2]&0xFF000000)>>24);                 //第8个字节
        cardinfo->SD_cid.ProdRev=tmp;                 
        tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16);                //第9个字节
        cardinfo->SD_cid.ProdSN=tmp<<24;          
        tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8);                 //第10个字节
        cardinfo->SD_cid.ProdSN|=tmp<<16;          
        tmp=(u8)(CID_Tab[2]&0x000000FF);                           //第11个字节
        cardinfo->SD_cid.ProdSN|=tmp<<8;                  
        tmp=(u8)((CID_Tab[3]&0xFF000000)>>24);                 //第12个字节
        cardinfo->SD_cid.ProdSN|=tmp;                             
        tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16);                 //第13个字节
        cardinfo->SD_cid.Reserved1|=(tmp&0xF0)>>4;
        cardinfo->SD_cid.ManufactDate=(tmp&0x0F)<<8;   
        tmp=(u8)((CID_Tab[3]&0x0000FF00)>>8);                //第14个字节
        cardinfo->SD_cid.ManufactDate|=tmp;                           
        tmp=(u8)(CID_Tab[3]&0x000000FF);                        //第15个字节
        cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
        cardinfo->SD_cid.Reserved2=1;         
        return errorstatus;
}
回复

使用道具 举报

5677

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

积分
45712
QQ
发表于 2019-2-18 00:15:48 | 显示全部楼层
孤独的行程者 发表于 2019-2-15 16:44
我已上传阿莫论坛的资料,你可以看下。我就是参考阿莫论坛的程序写的,不过有部分看不太懂,部分是照搬, ...

不好意思啊,这就帮不上了
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

3

主题

16

帖子

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-20 15:33:31 | 显示全部楼层
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用文件系统进行读写了。现在有个问题就是用fr=f_mkfs("0",1,4096)来格式化,实际容量有8g的,格式化完之后只有1g的容量。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|手机版|安富莱电子论坛 ( 鄂ICP备09023347号,公安机关备案号42010602000201 )

GMT+8, 2019-5-26 22:05 , Processed in 0.206760 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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