完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近需要在飞思卡尔的K60上使用SD卡,可是内部的SDHC模块始终调试不好,于是开始移植IO口模拟SPI与SD通讯,目前初始化成功,CMD0 CMD8 CMD55+ACMD41都返回相应有效值,CID,CSD都能读取成功,是金士顿8G Class10的卡,已经格式化成FAT32
但是读0扇区无法读到正确的MBR,读其他扇区值也不对,写扇区也写不进去,请问应如何解决这个问题 读0扇区奇怪的是能读到位于最后两字节的55 AA 但是MBR中 其余部分几乎读得0 这是winhex看的 这是IAR看内存看的,那个数据缓冲数组前面都是00,长度是520(最后8个字节不是读出来的) 初始化流程与这里的一致 http://blog.sina.com.cn/s/blog_4f09c0b50101636h.html相关读扇区的代码如下, //等待卡准备好 //返回值:0,准备好了;其他,错误代码 uint8 SD_WaitReady(void) { uint32 t=0; do { if(IO_SPI_SendRecvByte(0XFF)==0XFF)return 0;//OK t++; }while(t<0XFFFFFF);//等待 return 1; } //取消选择,释放SPI总线 void SD_DisSelect(void) { IO_SPI_CS_H(); IO_SPI_SendRecvByte(0xFF); //提供额外的8个时钟 } //选择sd卡,并且等待卡准备OK //返回值:0,成功;1,失败; uint8 SD_Select(void) { IO_SPI_CS_L(); if(SD_WaitReady()==0)return 0; //等待成功 SD_DisSelect(); return 1;//等待失败 } //从sd卡读取一个数据包的内容 //buf:数据缓存区 //len:要读取的数据长度. //返回值:0,成功;其他,失败; uint8 SD_ReadDataPack(uint8*buf,uint16 len) { if(SD_GetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE while(len--)//开始接收数据 { *buf=IO_SPI_SendRecvByte(0xFF); buf++; } //下面是2个伪CRC(dummy CRC) IO_SPI_SendRecvByte(0xFF); IO_SPI_SendRecvByte(0xFF); return 0;//读取成功 } DRESULT disk_read ( //读磁盘扇区 uint8 drv, /* 物理驱动编号 (0) */ uint8 *buff, /* 指向数据缓冲区来存储读到的数据 */ uint32 sector, /* 开始的扇区号 (LBA) */ uint8 count /* 扇区总数(1..255) */ ) { uint8 r1; uint8 res; SD_DisSelect();//取消上次片选 if(SD_Select()) return RES_ERROR;//片选失效 if(SD_type == SD_TYPE1) { sector<<=9; //转换为字节地址,分类可能有错 } if (count == 1) /* 单块读 */ { argument[0] = sector<<24; argument[1] = sector<<16; argument[2] = sector<<8; argument[3] = sector; r1 = SD_Send_Command(17, CMD_R1, response, argument); if(r1==0)//指令发送成功 { res=SD_ReadDataPack(buff,512);//接收512个字节 } r1 = IO_SPI_SendRecvByte(0xFF); r1 = IO_SPI_SendRecvByte(0xFF); } else { argument[0] = sector>>24; argument[1] = sector>>16; argument[2] = sector>>8; argument[3] = sector; r1 = SD_Send_Command(CMD18, CMD_R1, response, argument); if(r1==0)//指令发送成功 { do { r1=SD_ReadDataPack(buff,512);//接收512个字节 buff+=512; } while(--count && r1==0); } r1 = IO_SPI_SendRecvByte(0xFF); r1 = IO_SPI_SendRecvByte(0xFF); argument[0] = 0; argument[1] = 0; argument[2] = 0; argument[3] = 0; SD_Send_Command(CMD12, CMD_R1, response, argument); } SD_DisSelect();//取消片选 return RES_OK; } |
|
相关推荐
1个回答
|
|
消灭零回复,在这里帮你召唤大神!希望问题早日解决。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
298 浏览 1 评论
《DNESP32S3使用指南-IDF版_V1.6》第二十六章 INFRARED_RECEPTION实验
309 浏览 0 评论
826 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1911 浏览 2 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1427 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12031 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 01:37 , Processed in 0.532789 second(s), Total 72, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号