1、SD模块测试C程序#include REG52.H/*/unsigned char *SDInfo1=SD Init Success.;unsigned char *SDInfo2=SD Init Fail.;unsigned int xdata ReadBuffer128 ;unsigned int xdata WriteBuffer128 ;unsigned int BlockSize;unsigned long int BlockNR;/sbit sd_clk=P32;/sbit sd_cse=P30;/sbit sd_dai=P33; /Do/sbit sd_dao=P31; /DI
2、sbit sd_cse=P10; sbit sd_dao=P11;/DI sbit sd_clk=P12; sbit sd_dai=P13;/Dovoid Delay5us() unsigned char a=0; for(a=0;a40;a+) ;/*void SD_2Byte_Write(unsigned int IOData) unsigned char BitCounter; for (BitCounter=0;BitCounter16;BitCounter+) sd_clk=0;/CLK Low if(IOData&0x8000)/If the MSB of IOData is 1,
3、 then Do=1, else Do=0. sd_dao=1;/Do High else sd_dao=0;/Do Low sd_clk=1;/CLK High Delay5us(); IOData=IOData1;/Because the MSB is transmitted firstly, shift to next lower bit. /*void SD_Write(unsigned int IOData) unsigned char BitCounter; IOData=IOData8; for (BitCounter=0;BitCounter8;BitCounter+) sd_
4、clk=0;/CLK Low if(IOData&0x8000)/If the MSB of IOData is 1, then Do=1, else Do=0. sd_dao=1;/Do High else sd_dao=0;/Do Low sd_clk=1;/CLK High Delay5us(); IOData=IOData1;/Because the MSB is transmitted firstly, shift to next lower bit. /*unsigned int SD_2Byte_Read() unsigned int Buffer; unsigned char
5、BitCounter; Buffer=0; for (BitCounter=0;BitCounter16;BitCounter+) sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Buffer=Buffer1;/Because the MSB is transmitted firstly, shift to next lower bit. /Because the LSB will be damaged, we can not put this line under next line. if(sd_dai) Buffer+;/If SPI_D
6、in=1 then the LSB_of_Buffer=1. return Buffer;/*unsigned int SD_Read() unsigned int Buffer; unsigned char BitCounter; Buffer=0xffff; for (BitCounter=0;BitCounter8;BitCounter+) sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Buffer=Buffer1;/Because the MSB is transmitted firstly, shift to next lower
7、bit. /Because the LSB will be damaged, we can not put this line under next line. if(sd_dai) Buffer+;/If SPI_Din=1 then the LSB_of_Buffer=1. return Buffer;/*unsigned int SD_CMD_Write(unsigned int CMDIndex,unsigned long CMDArg,unsigned int ResType,unsigned int CSLowRSV)/ResType:Response Type, send 1 f
8、or R1; send 2 for R1b; send 3 for R2. /There are 7 steps need to do.(marked by 1-7) unsigned int temp,Response,Response2,CRC,MaximumTimes; Response2=0; MaximumTimes=10; CRC=0x0095;/0x0095 is only valid for CMD0 if (CMDIndex!=0) CRC=0x00ff; sd_cse=0;/1 CS Low SD_2Byte_Write(CMDIndex|0x0040)24);/2 Tra
9、nsmit Command_Index & 1st Byte of Command_Argument. SD_2Byte_Write(CMDArg&0x00ffff00)8); /2 2nd & 3rd Byte of Command_Argument SD_2Byte_Write(CMDArg&0x000000ff)8)+CRC); /2 4th Byte of Command_Argument & CRC only for CMD0 sd_dao=1;/3 Do High /3 Restore Do to High Level for (temp=0;temp8;temp+)/4 Prov
10、ide 8 extra clock after CMD sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); switch (ResType)/5 wait response case 1:/R1 do Response=SD_Read(); while (Response=0xffff); break; case 2:/R1b do Response=SD_Read(); while (Response=0xffff);/Read R1 firstly do Response2=SD_Read()-0xff00; while
11、 (Response2!=0);/Wait until the Busy_Signal_Token is non-zero break; case 3: Response=SD_2Byte_Read();break;/R2 if (CSLowRSV=0) sd_cse=1;/6 CS High (if the CMD has data block response CS should be kept low) for (temp=0;temp8;temp+)/7 Provide 8 extra clock after card response sd_clk=0;/CLK Low Delay5
12、us(); sd_clk=1;/CLK High Delay5us(); return Response;/*unsigned int SD_Reset_Card() unsigned int temp,MaximumTimes; MaximumTimes=10; for (temp=0;temp80;temp+)/Send 74+ Clocks sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); return SD_CMD_Write(0x0000,0x00000000,1,0);/Send CMD0/*unsigned
13、int SD_Initiate_Card()/Polling the card after reset unsigned int temp,Response,MaximumTimes; MaximumTimes=50; for(temp=0;tempMaximumTimes;temp+) Response=SD_CMD_Write(0x0037,0x00000000,1,0);/Send CMD55 Response=SD_CMD_Write(0x0029,0x00000000,1,0);/Send ACMD41 if (Response=0xff00) temp=MaximumTimes;
14、return Response;/*unsigned int SD_Get_CardInfo()/Read CSD register unsigned int temp,Response,MaximumTimes; MaximumTimes=50; for(temp=0;tempMaximumTimes;temp+) Response=SD_CMD_Write(9,0x00000000,1,1);/Send CMD9 if (Response=0xff00) temp=MaximumTimes; for (temp=0;temp8;temp+)/Provide 8 clock to romov
15、e the first byte of data response (0x00fe) sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); for (temp=0;temp8;temp+) ReadBuffertemp=SD_2Byte_Read();/Get the CSD data for (temp=0;temp16;temp+)/Provide 16 clock to remove the last 2 bytes of data response (CRC) sd_clk=0;/CLK Low Delay5us();
16、 sd_clk=1;/CLK High Delay5us(); sd_cse=1;/CS_High() for (temp=0;temp8;temp+)/Provide 8 extra clock after data response sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); BlockNR=(ReadBuffer314)&0x0003)+1;/Calcuate MULT BlockNR=BlockNR*(0x0002(ReadBuffer415)&0x0001)+1);/Calcuate Block_Numbe
17、r return Response;/*unsigned int SD_Overall_Initiation() unsigned int Response,Response_2; Response=0x0000; Response_2=0xff00; sd_dao=1;/1 Do High /1 Do must be High when there is no transmition do Response=SD_Reset_Card();/2 Send CMD0 while (Response!=0xff01); if (Response!=0xff01) Response_2+=8; /
18、Response=SD_CMD_Write(8,0x00000000,1,0);/Send CMD8 Response=SD_Initiate_Card();/3 Send CMD55+ACMD41 if (Response=0xff00) ; else Response_2+=4; ; do Response=SD_Get_CardInfo();/4 Read CSD while (Response!=0xff00); if (Response=0xff01) Response_2+=2; return Response_2;/ 0000|0000|0000|0000 Response_2/
19、 |_CSD Fail/ |_CMD55+ACMD41 Fail/ |_CMD0 Fail/*unsigned int SD_Get_CardID()/Read CID register unsigned int temp,Response,MaximumTimes; MaximumTimes=10; for(temp=0;tempMaximumTimes;temp+) Response=SD_CMD_Write(10,0x00000000,1,1);/Send CMD9 if (Response=0xff00) temp=MaximumTimes; for (temp=0;temp8;tem
20、p+)/Provide 8 clock to romove the first byte of data response (0x00fe) sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); for (temp=0;temp8;temp+) ReadBuffertemp=SD_2Byte_Read();/Get the CID data for (temp=0;temp16;temp+)/Provide 16 clock to remove the last 2 bytes of data response (CRC) s
21、d_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); sd_cse=1;/CS_High() for (temp=0;tempBlockNR) return 0xff20;/whether BlockAddress out of range? for(temp=0;tempMaximumTimes;temp+) Response=SD_CMD_Write(17,BlockAddress,1,1);/Send CMD17 if (Response=0xff00) temp=MaximumTimes; while (SD_Read(
22、)!=0xfffe) ; /这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte /如果您使用的单片机拥有1K以上的RAM请将%128去掉 for (temp=0;temp256;temp+) ReadBuffertemp%128=SD_2Byte_Read();/Get the readed data for (temp=0;temp16;temp+)/Provide 16 clock to remove the last 2 bytes of data response (CRC) sd_clk=0;/CLK Low Delay
23、5us(); sd_clk=1;/CLK High Delay5us(); sd_cse=1;/CS_High() for (temp=0;tempBlockNR) return 0xff20;/whether BlockAddress out of range? for(temp=0;tempMaximumTimes;temp+) Response=SD_CMD_Write(24,BlockAddress,1,1);/Send CMD24 if (Response=0xff00) temp=MaximumTimes; for (temp=0;temp8;temp+)/Provide 8 ex
24、tra clock after CMD response sd_clk=0;/CLK Low Delay5us(); sd_clk=1;/CLK High Delay5us(); SD_Write(0x00fe);/Send Start Block Token /这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte /如果您使用的单片机拥有1K以上的RAM请将%128去掉 for (temp=0;temp256;temp+) SD_2Byte_Write(WriteBuffertemp%128);/Data Block SD_2Byte_Write(0xffff);/Send 2 Bytes CRC Response=SD_Read(); while (SD_Read()!=0xffff) ; sd_cse=1;/CS_High() for (temp=0;temp8;temp+)/Provide 8 extra clock
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1