当前位置:文档之家› SD卡引脚及spi模式基本操作过程

SD卡引脚及spi模式基本操作过程

S D卡引脚及s p i模式基本操作过程SANY GROUP system office room 【SANYUA16H-注:S:电源供给I:输入O:采用推拉驱动的输出PP:采用推拉驱动的输入输出SD卡SPI模式下与单片机的连接图:SD卡支持两种总线方式:SD方式与SPI方式。

其中SD方式采用6线制,使用CLK、CMD、DAT0~DAT3进行数据通信。

而SPI方式采用4线制,使用CS、CLK、DataIn、DataOut进行数据通信。

SD方式时的数据传输速度与SPI方式要快,采用单片机对SD卡进行读写时一般都采用SPI模式。

写命令的例程:C程序//-------------------------------------------------------------------------向SD卡中写入命令,并返回回应的第二个字节//-------------------------------------------------------------------------unsignedchar Write_Command_SD(unsignedchar*CMD){unsignedchar tmp;unsignedchar retry=0;unsignedchar i;//禁止SD卡片选SPI_CS=1;//发送8个时钟信号Write_Byte_SD(0xFF);//使能SD卡片选SPI_CS=0;//向SD卡发送6字节命令for(i=0;i<0x06;i++){Write_Byte_SD(*CMD++);}//获得16位的回应Read_Byte_SD();//readthefirstbyte,ignoreit.do{//读取后8位tmp=Read_Byte_SD();retry++;}while((tmp==0xff)&&(retry<100));return(tmp);}初始化SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行后面的各项操作。

在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。

在初始化成功后,应尽量提高SPI的速率。

在刚开始要先发送至少74个时钟信号,这是必须的。

在很多读者的实验中,很多是因为疏忽了这一点,而使初始化不成功。

随后就是写入两个命令CMD0与CMD1,使SD卡进入SPI模式初始化时序图:初始化例程:C程序//----------------------------------------------------------初始化SD卡到SPI模式//----------------------------------------------------------unsignedchar SD_Init(){unsignedchar retry,temp;unsignedchar i;unsignedchar CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};SD_Port_Init();//初始化驱动端口Init_Flag=1;//将初始化标志置1for(i=0;i<0x0f;i++){Write_Byte_SD(0xff);//发送至少74个时钟信号读取CSD的时序:相应的程序例程如下:C程序//-------------------------------------------------------------------读SD卡的CSD寄存器共16字节返回0说明读取成功//-------------------------------------------------------------------unsignedchar Read_CSD_SD(unsignedchar*Buffer){//读取CSD寄存器的命令unsignedchar CMD[]={0x49,0x00,0x00,0x00,0x00,0xFF};unsignedchar temp;temp=SD_Read_Block(CMD,Buffer,16);//read16bytesreturn(temp);}4)读取SD卡信息综合上面对CID与CSD寄存器的读取,可以知道很多关于SD卡的信息,以下程序可以获取这些信息。

如下://----------------------------------------------------------------------//返回//SD卡的容量,单位为M//sectorcountandmultiplierMBareinu08==C_SIZE/(2^(9-C_SIZE_MULT))//SD卡的名称//----------------------------------------------------------------------void SD_get_volume_info(){unsignedchar i;unsignedchar c_temp[5];VOLUME_INFO_TYPESD_volume_Info,*vinf;vinf=&SD_volume_Info;//Initthepointoer;/读取CSD寄存器Read_CSD_SD(sectorBuffer.dat);//获取总扇区数vinf->sector_count=sectorBuffer.dat[6]&0x03;vinf->sector_count<<=8;vinf->sector_count+=sectorBuffer.dat[7];vinf->sector_count<<=2;vinf->sector_count+=(sectorBuffer.dat[8]&0xc0)>>6;//获取multipliervinf->sector_multiply=sectorBuffer.dat[9]&0x03;vinf->sector_multiply<<=1;vinf->sector_multiply+=(sectorBuffer.dat[10]&0x80)>>7;//获取SD卡的容量vinf->size_MB=vinf->sector_count>>(9-vinf->sector_multiply); //getthenameofthecardRead_CID_SD(sectorBuffer.dat);vinf->name[0]=sectorBuffer.dat[3];vinf->name[1]=sectorBuffer.dat[4];vinf->name[2]=sectorBuffer.dat[5];vinf->name[3]=sectorBuffer.dat[6];vinf->name[4]=sectorBuffer.dat[7];vinf->name[5]=0x00;//endflag}以上程序将信息装载到一个结构体中,这个结构体的定义如下:typedefstruct SD_VOLUME_INFO{//SD/SDCardinfounsignedint size_MB;unsignedchar sector_multiply;unsignedint sector_count;unsignedchar name[6];}VOLUME_INFO_TYPE;扇区读扇区读是对SD卡驱动的目的之一。

SD卡的每一个扇区中有512个字节,一次扇区读操作将把某一个扇区内的512个字节全部读出。

过程很简单,先写入命令,在得到相应的回应后,开始数据读取。

扇区读的时序:扇区读的程序例程:C程序unsignedchar SD_Read_Sector(unsignedlong sector,unsignedchar*buffer){unsignedchar retry;//命令16unsignedchar CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};unsignedchar temp;//地址变换由逻辑块地址转为字节地址sector=sector<<9;//sector=sector*512CMD[1]=((sector&0xFF000000)>>24);CMD[2]=((sector&0x00FF0000)>>16);CMD[3]=((sector&0x0000FF00)>>8);//将命令16写入SD卡retry=0;do{//为了保证写入命令一共写100次temp=Write_Command_MMC(CMD);retry++;if(retry==100){return(READ_BLOCK_ERROR);//blockwriteError!}}while(temp!=0);//ReadStartByteformMMC/SD-Card(FEh/StartByte)//Nowdataisready,youcanreaditout.while(Read_Byte_MMC()!=0xfe);readPos=0;SD_get_data(512,buffer);//512字节被读出到buffer中return0;}其中SD_get_data函数如下://---------------------------------------------------------获取数据到buffer中//---------------------------------------------------------void SD_get_data(unsignedint Bytes,unsignedchar*buffer){unsignedint j;for(j=0;j<Bytes;j++)*buffer++=Read_Byte_SD();}扇区写扇区写是SD卡驱动的另一目的。

每次扇区写操作将向SD卡的某个扇区中写入512个字节。

过程与扇区读相似,只是数据的方向相反与写入命令不同而已。

扇区写的时序:扇区写的程序例程:C程序//-----------------------------------------------------------------写512个字节到SD卡的某一个扇区中去返回0说明写入成功//-----------------------------------------------------------------unsignedchar SD_write_sector(unsignedlong addr,unsignedchar*Buffer){unsignedchar tmp,retry;unsignedint i;//命令24unsignedchar CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};addr=addr<<9;//addr=addr*512CMD[1]=((addr&0xFF000000)>>24);CMD[2]=((addr&0x00FF0000)>>16);CMD[3]=((addr&0x0000FF00)>>8);//写命令24到SD卡中去retry=0;do{//为了可靠写入,写100次tmp=Write_Command_SD(CMD);retry++;if(retry==100){return(tmp);//sendcommamdError!}}while(tmp!=0);//在写之前先产生100个时钟信号for(i=0;i<100;i++){Read_Byte_SD();}//写入开始字节Write_Byte_MMC(0xFE);//现在可以写入512个字节for(i=0;i<512;i++){Write_Byte_MMC(*Buffer++);}//CRC-ByteWrite_Byte_MMC(0xFF);//DummyCRCWrite_Byte_MMC(0xFF);//CRCCodetmp=Read_Byte_MMC();//readresponseif((tmp&0x1F)!=0x05)//写入的512个字节是未被接受{SPI_CS=1;return(WRITE_BLOCK_ERROR);//Error!}//等到SD卡不忙为止//因为数据被接受后,SD卡在向储存阵列中编程数据while(Read_Byte_MMC()!=0xff){};//禁止SD卡SPI_CS=1;return(0);//写入成功}此上内容在笔者的实验中都已调试通过。

相关主题