SD学习笔记一

来源:互联网 发布:贪吃蛇java代码详解 编辑:程序博客网 时间:2024/05/16 17:30

最近在做数据记录仪,把学习SD卡经理记录下来,以备以后需要。

一、SD卡初始化注意事项

1、SD的所有引脚加>=10K的上拉电阻(电源和地除外);

2、SD初始化频率不要大于400KHz,月低越好,我用的10KHz;

3、SD上电初始化之前,至少发送74个时钟周期(CS无效),已激活SD卡,激活后,读取SD返回0xFF;

4、命令操作结束后,最好再发8个CLK时钟,CS可以有效,也可以无效;

5、SPI模式默认关闭CRC教研,但是在发送ACMD41命令之前(不包括CMD55)要带校验码,所以CMD0和CMD8必须带校验码;

6、SPI命令的时钟和数据关系:


7、SD卡引脚排列:


8、SD卡初始化流程:


9、命令发出后,若64个CLK时钟后,没有返回有效数据,则认为SD发生严重错误。

10、经过测试表明:

   kingston2G卡在写入数据时候,返回xxx00101后,返回0xFF,表明SD卡忙,返回非0xFF表示已经写入到Flash中;
   SanDisk8G 卡在写入数据时候,返回xxx00101后,返回0x00,表明SD卡忙,返回非0x00表示已经写入到Flash中;


二、激活流程讲解

1、首次发送COM0命令,返回0x01,使SD卡进入待机模式;

2、发送CMD8,如果返回0x01,则卡位SD2.0,否则为SD1.X卡/MMC卡;返回0x01后,会在返回4个参数,0x00 0x00 xx xx,后面两个参数是你发什么,他回什么;

3、如果为SD2.0卡,发送CMD55,返回0x01,发送ACMD41,参数为0x40 0x00 0x00 0x00 ,如果返回0x00,则发送CMD58,鉴别SD是普通卡,还是高容量卡;

4、如果CMD8没有正确回应,发送CMD55,返回0x01,发送ACMD41,参数为0x00 0x00 0x00 0x00 ,如果返回0x00,则为SD1.X,否则为MMC卡;

5、MMC卡发送CMD1,返回0x00,至此初始化完毕;

6、高容量卡为扇区寻址;普通卡为字节寻址;

三、模拟SPI代码

#include "../Header/heard.h"








void delay_1ms(unsigned charcnt);






//1ms
void delay_1ms(unsigned charcnt)
{
unsigned short delay_times;
delay_times=1150;
while(cnt--)
{
while(delay_times--);
}
}




void Wake_SD(void)
{
unsigned char i;
unsigned char j;
SPI_CLK = 1;
SPI_CS = 1;
SPI_SO = 1;
for(i=0;i<80;i++)
{
j=1150/20; //20K频率唤醒SD卡
SPI_CLK=0;
while(j--);
j=1150/20; //20K频率唤醒SD卡
SPI_CLK=1;
while(j--);
}
SPI_CLK = 1;
}




void Init_SD_write(unsigned char*out)
{
unsigned char j;
union Commonwealth_8T_data;
SPI_CLK = 1;
T_data.byte_8=*out;
SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit7;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit6;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit5;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit4;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit3;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit2;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit1;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_SO = 1;
}




void Init_SD_write1(unsigned charout)
{
unsigned char j;
union Commonwealth_8T_data;
T_data.byte_8=out;
SPI_CLK = 1;


SPI_SO = T_data.Data_Uint8_bit.bit7;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit6;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit5;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit4;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit3;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit2;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit1;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_SO = T_data.Data_Uint8_bit.bit0;
SPI_CLK = 0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
j=1150/20; //20K频率初始化SD卡
while(j--);


// SPI_SO = 1;
}




unsigned char Init_SD_write2(unsigned charout)
{
unsigned char j;
unsigned char temp;
union Commonwealth_8T_data;
SPI_CLK = 1;
T_data.byte_8=out;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit7;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp =SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit6;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit5;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit4;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit3;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit2;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit1;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
temp  <<=0x01;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit0;
j=1150/20; //20K频率初始化SD卡
while(j--);
SPI_CLK = 1;
Nop();
Nop();
Nop();
temp |=SPI_SI;
j=1150/20; //20K频率初始化SD卡
while(j--);


SPI_SO =1;
return temp;
}








void SD_write3(unsigned char*out)
{
union Commonwealth_8T_data;
T_data.byte_8=*out;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit7;
SPI_CLK = 1;




SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit6;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit5;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit4;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit3;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit2;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit1;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit0;
SPI_CLK = 1;
Nop();
Nop();
Nop();
Nop();
SPI_SO = 1;
}


void SD_write4(unsigned char*out,unsigned shortDataL)
{
unsigned shorti;
union Commonwealth_8T_data;


for(i=0;i<DataL;i++)
{
T_data.byte_8=out[i];

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit7;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit6;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit5;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit4;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit3;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit2;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit1;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit0;
SPI_CLK = 1;
}
Nop();
Nop();
Nop();
Nop();
SPI_SO = 1;
}


void SD_write5(unsigned char*out,unsigned shortDataL,unsigned char* rxdData,unsigned short rxDLong)
{
unsigned shorti;
unsigned char j;
union Commonwealth_8T_data;


for(i=0;i<DataL;i++)
{
T_data.byte_8=out[i];

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit7;
SPI_CLK = 1;


SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit6;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit5;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit4;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit3;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit2;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit1;
SPI_CLK = 1;

SPI_CLK = 0;
SPI_SO = T_data.Data_Uint8_bit.bit0;
SPI_CLK = 1;
}
Nop();
Nop();
Nop();
Nop();
SPI_SO = 1;


for(i<0;i<rxDLong;i++)
{
SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit7=SPI_SI;


SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit6=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit5=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit4=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit3=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit2=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit1=SPI_SI;

SPI_CLK = 0;
SPI_CLK = 1;
T_data.Data_Uint8_bit.bit0=SPI_SI;
rxdData[i]=T_data.byte_8;
}
}


四、SD卡初始化函数

//1:MMC
//2:SD1.0/1.1
//3:SD2.0
//4:SDHC
unsigned char SD_Edition;
unsigned char erro;

//主函数
void main(void)
{
char ph[]="/j.txt";
Init_Variable();
Init_cpu();
erro=0;
LED2=0;
LED3=1;
delay_ms(500);



LED2=1;
if(erro)
{
LED3=1;
}
else
{
LED3=0;
}
while(1);
}




void Init_Variable(void)
{
SD_Edition=0;
}


unsigned char Init_SD(void)
{
erro=Init_SD_wake();//激活SD卡


if(!erro)
erro=Init_SD_CMD0();//进入SPI模式

if(!erro)
{
erro=Init_SD_CMD8();//鉴别SD卡2.0或者1.0
if(erro)
{
erro=Init_SD_CMD41(0x00);//SD1.0/1.1
if(erro)
{
erro=Init_SD_CMD1();//MMC
if(erro==0x00)
{
SD_Edition=1;
}
}
else
{
SD_Edition=2;
}
}
else
{
erro=Init_SD_CMD41(0x40);//SD2.0
if(erro==0x00)//鉴别SD2.0版本
{
erro=Init_SD_CMD58(&SD_Edition);
}
}
}
return erro;
}


void Init_cpu(void)
{
Init_IO();
}


//1ms
void delay_ms(unsigned charcnt)
{
unsigned short delay_times;
while(cnt--)
{
delay_times=1150;
while(delay_times--);
}
}


unsigned char Init_SD_wake(void)
{
unsigned char i=0;
unsigned char wake_temp;
do
{
Wake_SD(); //唤醒SD卡
wake_temp=0;
SPI_CS = 0;
wake_temp=Init_SD_write2(0xFF);
i++;
SPI_CS = 1;
}
while((wake_temp!=0xFF) &&(i<200));//SD卡激活后,返回0xFF,没有激活返回0x00
if(i==200)
{
return 1;
}
return 0;
}




unsigned char Init_SD_CMD0(void)
{
unsigned char i=0;
unsigned char j;
unsigned char wake_temp;
unsigned char CMD0[]={0x40,0x00,0x00,0x00,0x00,0x95};
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write1(CMD0[j]);
}
j=0;
wake_temp=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));//64个CLK后超时
i++;
SPI_CS = 1;
Init_SD_write1(0xFF);
}
while((wake_temp!=0x01) && (i<200));
if(i==200)
{
return 2;
}
return 0;
}


//只有SD2.0卡支持CMD8命令,SD1.0/1.1不支持此命令
unsigned char Init_SD_CMD8(void)
{
unsigned char i=0;
unsigned char j;
unsigned char wake_temp;
unsigned char CMD8[]={0x48,0x00,0x00,0x01,0xAA,0x87};
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write(CMD8+j);
}
j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
i++;
if(wake_temp!=0x01)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
}
while((wake_temp!=0x01) &&(i<200));
if(i==200)
{
return 3;
}
memset(CMD8,0x00,0x06);
CMD8[0]=wake_temp;
CMD8[1]=Init_SD_write2(0xFF);
CMD8[2]=Init_SD_write2(0xFF);
CMD8[3]=Init_SD_write2(0xFF);
CMD8[4]=Init_SD_write2(0xFF);
// CMD8[5]=Init_SD_write2(0xFF);




if(0x00!=CMD8[1])
{
return 3;
}


if(0x00!=CMD8[2])
{
return 3;
}


if(0x01!=CMD8[3])
{
return 3;
}


if(0xAA!=CMD8[4])
{
return 3;
}


Init_SD_write1(0xFF);
SPI_CS = 1;
return 0;
}


//CMD55+CMD41
unsigned char Init_SD_CMD41(unsigned charHCS)
{
unsigned char CMD55[]={0x77,0x00,0x00,0x00,0x00,0x65};//支持下一条命令是一条操作命令
unsigned char CMD41[]={0x69,0x40,0x00,0x00,0x00,0x01};
unsigned char i=0;
unsigned char j,m;
unsigned char wake_temp;


if((0x40==HCS) || (0x00==HCS))
{
CMD41[1]=HCS;
}


m=0;
do
{
i=0;
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write(CMD55+j);
}
j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
i++;
if(wake_temp!=0x01)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
}//CMD55
while((wake_temp!=0x01) &&(i<200));

if(i>=200)
{
return 4;
}


SPI_CS = 1;
Init_SD_write1(0xFF);
SPI_CS = 0;


for(j=0;j<6;j++)
{
Init_SD_write(CMD41+j);
}


j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));


m++;
if(wake_temp!=0x00)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
}
while((wake_temp!=0x00) &&(m<200));//等待初始化时间,未就绪返回0x01,就绪返回0x00


if(m>=200)
{
return 5;
}


Init_SD_write1(0xFF);
SPI_CS = 1;
return 0;




/*
i=0;
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write(CMD55+j);
}
j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
i++;
if(j>=8)
{
SPI_CS = 1;
}
}//CMD55
while((wake_temp!=0x01) &&(i<200));

if(i==200)
{
return 4;
}
SPI_CS = 1;
Init_SD_write1(0xFF);
*/

/***********************************/
/*
i=0;
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write(CMD41+j);
}


j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
i++;

if(wake_temp!=0x00)
{
SPI_CS = 1;
}
}
while((wake_temp!=0x00) &&(i<200));//等待初始化时间,未就绪返回0x01,就绪返回0x00


if(i==200)
{
return 5;
}
*/


/*
i=0;
do
{
j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
}
while((wake_temp!=0x00) && (j<200));
if(i==200)
{
return 5;
}
*/
}




//用于初始化MMC卡
unsigned char Init_SD_CMD1(void)
{
unsigned char i=0;
unsigned char j;
unsigned char wake_temp;
unsigned char CMD1[]={0x41,0x00,0x00,0x00,0x00,0xF9};
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write1(CMD1[j]);
}
j=0;
wake_temp=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));//64个CLK后超时
i++;
SPI_CS = 1;
Init_SD_write1(0xFF);
}
while((wake_temp!=0x00) && (i<200));
if(i==200)
{
return 6;
}
return 0;
}






//鉴别SD2.0版本
unsigned char Init_SD_CMD58(unsigned char* sd_var)
{
unsigned char i=0;
unsigned char j=0;
unsigned char wake_temp=0;
unsigned char CMD58[]={0x7A,0x00,0x00,0x00,0x00,0xFD};
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write1(CMD58[j]);
}
j=0;
wake_temp=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));//64个CLK后超时
i++;

if(wake_temp!=0x00)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
}
while((wake_temp!=0x00) && (i<200));


if(i==200)
{
return 7;
}




// CMD58[0]=wake_temp;
CMD58[1]=Init_SD_write2(0xFF);
CMD58[2]=Init_SD_write2(0xFF);
CMD58[3]=Init_SD_write2(0xFF);
CMD58[4]=Init_SD_write2(0xFF);


if(CMD58[1] & 0x40)
{
*sd_var=4;
}
else
{
*sd_var=3;
}


Init_SD_write1(0xFF);
SPI_CS = 1;
return 0;


}


//地址为扇区地址
bool SD_WriteSector(unsigned longadress,unsigned char*buffer)
{
unsigned shorti;
unsigned char j;
unsigned char wake_temp;
unsigned char CMD24[]={0x58,0x00,0x00,0x00,0x00,0xFF};


if(!SD_Edition)
{
return false;
}




if(SD_Edition!=0x04)
{
adress<<=0x09;//普通卡字节寻址,SDHC卡扇区寻址
}


CMD24[1]=adress>>24;
CMD24[2]=adress>>16;
CMD24[3]=adress>>8;
CMD24[4]=adress;




i=0;
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write1(CMD24[j]);
}


j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
if(wake_temp!=0x00)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
i++;
}
while((wake_temp!=0x00) && (i<200));
if(i==200)
{
return false;
}


Init_SD_write1(0xFF);
Init_SD_write1(0xFF);




Init_SD_write1(0xFE);
for(i=0;i<512;i++)
{
Init_SD_write1(buffer[i]);
}
Init_SD_write1(0xFF);
Init_SD_write1(0xFF);

j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while(((wake_temp & 0x1F)!=0x05) && (j<8));
if(j>=8)
{
SPI_CS = 1;
return false;
}


j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp!=0x00) && (j<200));
if(j>=200)
{
SPI_CS = 1;
return false;
}
Init_SD_write1(0xFF);
SPI_CS = 1;
return true;
}






//地址为扇区地址
bool SD_ReadSector(unsigned longadress,unsigned char*buffer)
{
unsigned shorti;
unsigned char j;
unsigned char wake_temp;
unsigned char CMD17[]={0x51,0x00,0x00,0x00,0x00,0xFF};


if(!SD_Edition)
{
return false;
}


if(SD_Edition!=0x04)
{
adress<<=0x09;//普通卡字节寻址,SDHC卡扇区寻址
}



CMD17[1]=adress>>24;
CMD17[2]=adress>>16;
CMD17[3]=adress>>8;
CMD17[4]=adress;


i=0;
do
{
SPI_CS = 0;
for(j=0;j<6;j++)
{
Init_SD_write1(CMD17[j]);
}


j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp==0xFF) && (j<8));
if(wake_temp!=0x00)
{
SPI_CS = 1;
Init_SD_write1(0xFF);
}
i++;
}
while((wake_temp!=0x00) && (i<200));


if(i==200)
{
return false;
}
j=0;
do
{
wake_temp=Init_SD_write2(0xFF);
j++;
}
while((wake_temp!=0xFE) && (j<200));


if(j>=200)
{
SPI_CS = 1;
return false;
}


for(i=0;i<512;i++)
{
buffer[i]=Init_SD_write2(0xFF);
}


Init_SD_write1(0xFF);
Init_SD_write1(0xFF);
SPI_CS = 1;
Init_SD_write1(0xFF);
Init_SD_write1(0xFF);
return true;


}


0 0