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
相关推荐: