第一范文网 - 专业文章范例文档资料分享平台

STM32读写SD卡要点 - 图文

来源:用户分享 时间:2025/6/24 23:52:29 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

u8 SD_GetCSD(u8 *csd_data) {

u8 r1;

r1=SD_SendCommand(CMD9,0,0xFF);//发CMD9命令,读 CSD

if(r1)return r1; //没返回正确应答,则退出,报错

SD_ReceiveData(csd_data, 16, RELEASE);//接收16个字节的数据

return 0;

}

//获取SD卡的容量(字节)

//返回值:0: 取容量出错

// 其他:SD卡的容量(字节)

u32 SD_GetCapacity(void) {

u8 csd[16]; u32 Capacity; u8 r1; u16 i;

u16 temp;

//取CSD信息,如果期间出错,返回0

if(SD_GetCSD(csd)!=0) return 0; //如果为SDHC卡,按照下面方式计算

if((csd[0]&0xC0)==0x40) {

Capacity=((u32)csd[8])<<8;

Capacity+=(u32)csd[9]+1;

Capacity = (Capacity)*1024;//得到扇区数 Capacity*=512;//得到字节数 } else {

i = csd[6]&0x03; i<<=8; i += csd[7]; i<<=2;

i += ((csd[8]&0xc0)>>6); //C_SIZE_MULT r1 = csd[9]&0x03; r1<<=1;

r1 += ((csd[10]&0x80)>>7); r1+=2;//BLOCKNR temp = 1; while(r1)

307

{

temp*=2; r1--;

}

Capacity = ((u32)(i+1))*((u32)temp); // READ_BL_LEN i = csd[5]&0x0f; //BLOCK_LEN temp = 1; while(i) {

temp*=2; i--;

}

//The final result

Capacity *= (u32)temp;//字节为单位 }

return (u32)Capacity; }

//读SD卡的一个block

//输入:u32 sector 取地址(sector值,非物理地址)

// u8 *buffer 数据存储地址(大小至少512byte)

//返回值:0: 成功 // other:失败

u8 SD_ReadSingleBlock(u32 sector, u8 *buffer) {

u8 r1;

//设置为高速模式

SPIx_SetSpeed(SPI_SPEED_4);

//如果不是SDHC,给定的是sector地址,将其转换成byte地址

if(SD_Type!=SD_TYPE_V2HC) {

sector = sector<<9;

}

r1 = SD_SendCommand(CMD17, sector, 0);//读命令 if(r1 != 0x00)return r1;

r1 = SD_ReceiveData(buffer, 512, RELEASE); if(r1 != 0)return r1; //读数据出错!

else return 0;

}

/////////////////下面2个函数为USB读写所需要的/////////////////////////

308

//定义SD卡的块大小 #define BLOCK_SIZE 512

//写入MSD/SD数据

//pBuffer:数据存放区 //ReadAddr:写入的首地址 //NumByteToRead:要写入的字节数 //返回值:0,写入完成 // 其他,写入失败

u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite) {

u32 i,NbrOfBlock = 0, Offset = 0; u32 sector; u8 r1;

NbrOfBlock = NumByteToWrite / BLOCK_SIZE;//得到要写入的块的数目 SD_CS=0;

while (NbrOfBlock--)//写入一个扇区 {

sector=WriteAddr+Offset;

if(SD_Type==SD_TYPE_V2HC)sector>>=9;//执行与普通操作相反的操作 r1=SD_SendCommand_NoDeassert(CMD24,sector,0xff);//写命令 if(r1) {

SD_CS=1;

return 1;//应答不正确,直接返回 }

SPIx_ReadWriteByte(0xFE);//放起始令牌0xFE

//放一个sector的数据

for(i=0;i<512;i++)SPIx_ReadWriteByte(*pBuffer++); //发2个Byte的 dummy CRC

SPIx_ReadWriteByte(0xff); SPIx_ReadWriteByte(0xff);

if(SD_WaitDataReady())//等待SD卡数据写入完成

{

SD_CS=1; return 2; }

Offset += 512; }

//写入完成,片选置1

SD_CS=1;

SPIx_ReadWriteByte(0xff); return 0;

309

}

//读取MSD/SD数据

//pBuffer:数据存放区

//ReadAddr:读取的首地址

//NumByteToRead:要读出的字节数 //返回值:0,读出完成 // 其他,读出失败

u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead) {

u32 NbrOfBlock=0,Offset=0; u32 sector=0; u8 r1=0;

NbrOfBlock=NumByteToRead/BLOCK_SIZE; SD_CS=0;

while (NbrOfBlock --) {

sector=ReadAddr+Offset;

if(SD_Type==SD_TYPE_V2HC)sector>>=9;//执行与普通操作相反的操作

r1=SD_SendCommand_NoDeassert(CMD17,sector,0xff);//读命令

if(r1)//命令发送错误 {

SD_CS=1; return r1;

}

r1=SD_ReceiveData(pBuffer,512,RELEASE); if(r1)//读数错误 {

SD_CS=1; return r1; }

pBuffer+=512; Offset+=512; }

SD_CS=1;

SPIx_ReadWriteByte(0xff); return 0;

}

////////////////////////////////////////////////////////////////////////// //写入SD卡的一个block(未实际测试过)

//输入:u32 sector 扇区地址(sector值,非物理地址)

310

搜索更多关于: STM32读写SD卡要点 - 图文 的文档
STM32读写SD卡要点 - 图文.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c1ga2m0vtzp47le14lopx1jxus0hl5300vw2_4.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top