SD模块测试C程序.docx
《SD模块测试C程序.docx》由会员分享,可在线阅读,更多相关《SD模块测试C程序.docx(16页珍藏版)》请在冰豆网上搜索。
SD模块测试C程序
#include"REG52.H"
////////////////////////****************/
unsignedchar*SDInfo1="SDInitSuccess.";
unsignedchar*SDInfo2="SDInitFail.";
unsignedintxdataReadBuffer[128];
unsignedintxdataWriteBuffer[128];
unsignedintBlockSize;
unsignedlongintBlockNR;
//sbitsd_clk=P3^2;
//sbitsd_cse=P3^0;
//sbitsd_dai=P3^3;//Do
//sbitsd_dao=P3^1;//DI
sbitsd_cse=P1^0;
sbitsd_dao=P1^1;//DI
sbitsd_clk=P1^2;
sbitsd_dai=P1^3;//Do
voidDelay5us()
{
unsignedchara=0;
for(a=0;a<40;a++)
;
}
//********************************************
voidSD_2Byte_Write(unsignedintIOData)
{
unsignedcharBitCounter;
for(BitCounter=0;BitCounter<16;BitCounter++)
{
sd_clk=0;//CLKLow
if(IOData&0x8000)//IftheMSBofIODatais1,thenDo=1,elseDo=0.
sd_dao=1;//DoHigh
else
sd_dao=0;//DoLow
sd_clk=1;//CLKHigh
Delay5us();
IOData=IOData<<1;//BecausetheMSBistransmittedfirstly,shifttonextlowerbit.
}
}
//********************************************
voidSD_Write(unsignedintIOData)
{
unsignedcharBitCounter;
IOData=IOData<<8;
for(BitCounter=0;BitCounter<8;BitCounter++)
{
sd_clk=0;//CLKLow
if(IOData&0x8000)//IftheMSBofIODatais1,thenDo=1,elseDo=0.
sd_dao=1;//DoHigh
else
sd_dao=0;//DoLow
sd_clk=1;//CLKHigh
Delay5us();
IOData=IOData<<1;//BecausetheMSBistransmittedfirstly,shifttonextlowerbit.
}
}
//********************************************
unsignedintSD_2Byte_Read()
{
unsignedintBuffer;
unsignedcharBitCounter;
Buffer=0;
for(BitCounter=0;BitCounter<16;BitCounter++)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Buffer=Buffer<<1;//BecausetheMSBistransmittedfirstly,shifttonextlowerbit.
//BecausetheLSBwillbedamaged,wecannotputthislineundernextline.
if(sd_dai)
Buffer++;//IfSPI_Din=1thentheLSB_of_Buffer=1.
}
returnBuffer;
}
//********************************************
unsignedintSD_Read()
{
unsignedintBuffer;
unsignedcharBitCounter;
Buffer=0xffff;
for(BitCounter=0;BitCounter<8;BitCounter++)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Buffer=Buffer<<1;//BecausetheMSBistransmittedfirstly,shifttonextlowerbit.
//BecausetheLSBwillbedamaged,wecannotputthislineundernextline.
if(sd_dai)
Buffer++;//IfSPI_Din=1thentheLSB_of_Buffer=1.
}
returnBuffer;
}
//********************************************
unsignedintSD_CMD_Write(unsignedintCMDIndex,unsignedlongCMDArg,unsignedintResType,unsignedintCSLowRSV)//ResType:
ResponseType,send1forR1;send2forR1b;send3forR2.
{//Thereare7stepsneedtodo.(markedby[1]-[7])
unsignedinttemp,Response,Response2,CRC,MaximumTimes;
Response2=0;
MaximumTimes=10;
CRC=0x0095;//0x0095isonlyvalidforCMD0
if(CMDIndex!
=0)CRC=0x00ff;
sd_cse=0;//[1]CSLow
SD_2Byte_Write(((CMDIndex|0x0040)<<8)+(CMDArg>>24));//[2]TransmitCommand_Index&1stByteofCommand_Argument.
SD_2Byte_Write((CMDArg&0x00ffff00)>>8);//[2]2nd&3rdByteofCommand_Argument
SD_2Byte_Write(((CMDArg&0x000000ff)<<8)+CRC);//[2]4thByteofCommand_Argument&CRConlyforCMD0
sd_dao=1;//[3]DoHigh
//[3]RestoreDotoHighLevel
for(temp=0;temp<8;temp++)//[4]Provide8extraclockafterCMD
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
switch(ResType)//[5]waitresponse
{
case1:
//R1
{
do
Response=SD_Read();
while(Response==0xffff);
break;
}
case2:
//R1b
{
do
Response=SD_Read();
while(Response==0xffff);//ReadR1firstly
do
Response2=SD_Read()-0xff00;
while(Response2!
=0);//WaituntiltheBusy_Signal_Tokenisnon-zero
break;
}
case3:
Response=SD_2Byte_Read();break;//R2
}
if(CSLowRSV==0)sd_cse=1;//[6]CSHigh(iftheCMDhasdatablockresponseCSshouldbekeptlow)
for(temp=0;temp<8;temp++)//[7]Provide8extraclockaftercardresponse
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
returnResponse;
}
//********************************************
unsignedintSD_Reset_Card()
{
unsignedinttemp,MaximumTimes;
MaximumTimes=10;
for(temp=0;temp<80;temp++)//Send74+Clocks
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
returnSD_CMD_Write(0x0000,0x00000000,1,0);//SendCMD0
}
//********************************************
unsignedintSD_Initiate_Card()//Pollingthecardafterreset
{
unsignedinttemp,Response,MaximumTimes;
MaximumTimes=50;
for(temp=0;temp{
Response=SD_CMD_Write(0x0037,0x00000000,1,0);//SendCMD55
Response=SD_CMD_Write(0x0029,0x00000000,1,0);//SendACMD41
if(Response==0xff00)
temp=MaximumTimes;
}
returnResponse;
}
//********************************************
unsignedintSD_Get_CardInfo()//ReadCSDregister
{
unsignedinttemp,Response,MaximumTimes;
MaximumTimes=50;
for(temp=0;temp{
Response=SD_CMD_Write(9,0x00000000,1,1);//SendCMD9
if(Response==0xff00)
temp=MaximumTimes;
}
for(temp=0;temp<8;temp++)//Provide8clocktoromovethefirstbyteofdataresponse(0x00fe)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
for(temp=0;temp<8;temp++)ReadBuffer[temp]=SD_2Byte_Read();//GettheCSDdata
for(temp=0;temp<16;temp++)//Provide16clocktoremovethelast2bytesofdataresponse(CRC)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
sd_cse=1;//CS_High()
for(temp=0;temp<8;temp++)//Provide8extraclockafterdataresponse
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
BlockNR=((ReadBuffer[3]<<2)&0x0fff)+((ReadBuffer[4]>>14)&0x0003)+1;//CalcuateMULT
BlockNR=BlockNR*(0x0002<<(((ReadBuffer[4]<<1)&0x0007)+((ReadBuffer[5]>>15)&0x0001)+1));//CalcuateBlock_Number
returnResponse;
}
//********************************************
unsignedintSD_Overall_Initiation()
{
unsignedintResponse,Response_2;
Response=0x0000;
Response_2=0xff00;
sd_dao=1;//[1]DoHigh
//[1]DomustbeHighwhenthereisnotransmition
do
Response=SD_Reset_Card();//[2]SendCMD0
while(Response!
=0xff01);
if(Response!
=0xff01)Response_2+=8;
//Response=SD_CMD_Write(8,0x00000000,1,0);//SendCMD8
Response=SD_Initiate_Card();//[3]SendCMD55+ACMD41
if(Response==0xff00)
;
else
{
Response_2+=4;
;
}
do
Response=SD_Get_CardInfo();//[4]ReadCSD
while(Response!
=0xff00);
if(Response==0xff01)Response_2+=2;
returnResponse_2;
//0000|0000||0000|0000Response_2
//|||_CSDFail
//||__CMD55+ACMD41Fail
//|___CMD0Fail
}
//********************************************
unsignedintSD_Get_CardID()//ReadCIDregister
{
unsignedinttemp,Response,MaximumTimes;
MaximumTimes=10;
for(temp=0;temp{
Response=SD_CMD_Write(10,0x00000000,1,1);//SendCMD9
if(Response==0xff00)
temp=MaximumTimes;
}
for(temp=0;temp<8;temp++)//Provide8clocktoromovethefirstbyteofdataresponse(0x00fe)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
for(temp=0;temp<8;temp++)ReadBuffer[temp]=SD_2Byte_Read();//GettheCIDdata
for(temp=0;temp<16;temp++)//Provide16clocktoremovethelast2bytesofdataresponse(CRC)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
sd_cse=1;//CS_High()
for(temp=0;temp<8;temp++)//Provide8extraclockafterdataresponse
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
returnResponse;
}
//********************************************
unsignedintRead_Single_Block(unsignedlongintBlockAddress)
{
unsignedinttemp,Response,MaximumTimes;
MaximumTimes=10;
if(BlockAddress>BlockNR)return0xff20;//whetherBlockAddressoutofrange?
for(temp=0;temp{
Response=SD_CMD_Write(17,BlockAddress,1,1);//SendCMD17
if(Response==0xff00)
temp=MaximumTimes;
}
while(SD_Read()!
=0xfffe){;}
//这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte
//如果您使用的单片机拥有1K以上的RAM请将"%128"去掉
for(temp=0;temp<256;temp++)ReadBuffer[temp%128]=SD_2Byte_Read();//Getthereadeddata
for(temp=0;temp<16;temp++)//Provide16clocktoremovethelast2bytesofdataresponse(CRC)
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
sd_cse=1;//CS_High()
for(temp=0;temp<8;temp++)//Provide8extraclockafterdataresponse
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
returnResponse;
}
//********************************************
unsignedintWrite_Single_Block(unsignedlongintBlockAddress)
{
unsignedinttemp,Response,MaximumTimes;
MaximumTimes=10;
if(BlockAddress>BlockNR)return0xff20;//whetherBlockAddressoutofrange?
for(temp=0;temp{
Response=SD_CMD_Write(24,BlockAddress,1,1);//SendCMD24
if(Response==0xff00)
temp=MaximumTimes;
}
for(temp=0;temp<8;temp++)//Provide8extraclockafterCMDresponse
{
sd_clk=0;//CLKLow
Delay5us();
sd_clk=1;//CLKHigh
Delay5us();
}
SD_Write(0x00fe);//SendStartBlockToken
//这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte
//如果您使用的单片机拥有1K以上的RAM请将"%128"去掉
for(temp=0;temp<256;temp++)SD_2Byte_Write(WriteBuffer[temp%128]);//DataBlock
SD_2Byte_Write(0xffff);//Send2BytesCRC
Response=SD_Read();
while(SD_Read()!
=0xffff){;}
sd_cse=1;//CS_High()
for(temp=0;temp<8;temp++)//Provide8extraclock