}
//读取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
// u8 *buffer 数据存储地址(大小至少512byte) //返回值:0: 成功
// other:失败
u8 SD_WriteSingleBlock(u32 sector, const u8 *data) {
u8 r1; u16 i;
u16 retry;
//设置为高速模式
//SPIx_SetSpeed(SPI_SPEED_HIGH);
//如果不是SDHC,给定的是sector地址,将其转换成byte地址
if(SD_Type!=SD_TYPE_V2HC) {
sector = sector<<9; }
r1 = SD_SendCommand(CMD24, sector, 0x00); if(r1 != 0x00) {
return r1; //应答不正确,直接返回
}
//开始准备数据传输 SD_CS=0;
//先放3个空数据,等待SD卡准备好 SPIx_ReadWriteByte(0xff);
SPIx_ReadWriteByte(0xff); SPIx_ReadWriteByte(0xff); //放起始令牌0xFE
SPIx_ReadWriteByte(0xFE); //放一个sector的数据
for(i=0;i<512;i++) {
SPIx_ReadWriteByte(*data++); }
//发2个Byte的 dummy CRC
SPIx_ReadWriteByte(0xff); SPIx_ReadWriteByte(0xff);
//等待SD卡应答
r1 = SPIx_ReadWriteByte(0xff);
311
if((r1&0x1F)!=0x05) {
SD_CS=1; return r1;
}
//等待操作完成 retry = 0;
while(!SPIx_ReadWriteByte(0xff)) {
retry++;
if(retry>0xfffe) //如果长时间写入没有完成,报错退出
{
SD_CS=1;
return 1; //写入超时返回1
} }
//写入完成,片选置1
}
SD_CS=1;
SPIx_ReadWriteByte(0xff); return 0;
//读SD卡的多个block(实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
// u8 *buffer 数据存储地址(大小至少512byte) // u8 count 连续读count个block
//返回值:0: 成功 // other:失败
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count) {
u8 r1;
//SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式 //如果不是SDHC,将sector地址转成byte地址
if(SD_Type!=SD_TYPE_V2HC)sector = sector<<9; //SD_WaitDataReady(); //发读多块命令
r1 = SD_SendCommand(CMD18, sector, 0);//读命令 if(r1 != 0x00)return r1; do//开始接收数据 {
if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00)break;
312
buffer += 512; } while(--count);
//全部传输完毕,发送停止命令 SD_SendCommand(CMD12, 0, 0); //释放总线
SD_CS=1;
SPIx_ReadWriteByte(0xFF);
if(count != 0)return count; //如果没有传完,返回剩余个数
else return 0; }
//写入SD卡的N个block(未实际测试过)
//输入:u32 sector 扇区地址(sector值,非物理地址)
// u8 *buffer 数据存储地址(大小至少512byte)
// u8 count 写入的block数目 //返回值:0: 成功
// other:失败
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count) {
u8 r1;
u16 i;
//SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式
if(SD_Type != SD_TYPE_V2HC)sector = sector<<9;//如果不是 SDHC,给定的是
sector地址,将其转换成byte地址
if(SD_Type != SD_TYPE_MMC) r1 = SD_SendCommand(ACMD23, count, 0x00);//
如果目标卡不是MMC卡,启用ACMD23指令使能预擦除
r1 = SD_SendCommand(CMD25, sector, 0x00);//发多块写入指令
if(r1 != 0x00)return r1; //应答不正确,直接返回
SD_CS=0;//开始准备数据传输
SPIx_ReadWriteByte(0xff);//先放3个空数据,等待SD卡准备好
SPIx_ReadWriteByte(0xff);
//--------下面是N个 sector写入的循环部分
do {
//放起始令牌0xFC 表明是多块写入
SPIx_ReadWriteByte(0xFC); //放一个sector的数据
for(i=0;i<512;i++) {
SPIx_ReadWriteByte(*data++); }
//发2个Byte的dummy CRC SPIx_ReadWriteByte(0xff);
313
SPIx_ReadWriteByte(0xff); //等待SD卡应答
r1 = SPIx_ReadWriteByte(0xff); if((r1&0x1F)!=0x05) {
SD_CS=1; //如果应答为报错,则带错误代码直接退出
return r1; }
//等待SD卡写入完成
if(SD_WaitDataReady()==1) {
SD_CS=1; //等待SD卡写入完成超时,直接退出报错
return 1; }
}while(--count);//本sector数据传输完成 //发结束传输令牌0xFD
r1 = SPIx_ReadWriteByte(0xFD); if(r1==0x00) {
count = 0xfe; }
if(SD_WaitDataReady()) //等待准备好 {
SD_CS=1; return 1; }
//写入完成,片选置1
SD_CS=1;
SPIx_ReadWriteByte(0xff);
return count; //返回count值,如果写完则count=0,否则count=1
}
//在指定扇区,从offset开始读出bytes个字节
//输入:u32 sector 扇区地址(sector值,非物理地址) // u8 *buf 数据存储地址(大小<=512byte)
// u16 offset 在扇区里面的偏移量 // u16 bytes 要读出的字节数
//返回值:0: 成功
// other:失败
u8 SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes)
{
314