SD card pins circuit diagram and working principle

For the hardware structure of the SD card, a very detailed description in the official documents, such as memory structures within the SD card, memory unit organization and so on. To achieve its read and write, the core is its timing, the author after the actual test, using 51 single successful implementation of read and write SD card sector, and an assessment of its read and write speed. The following first to explain the timing of read and write SD card.

(1)  SD card pin definitions :

SD card pin functions in detail:

Note: S: power supply I: Input O: push-pull output driver
PP: push-pull output drive input

SD card supports two bus ways: SD mode and SPI mode. Wherein the 6-wire SD mode, using CLK, CMD, DAT0 ~ DAT3 data communication. And 4-wire SPI mode, the use of CS, CLK, DataIn, DataOut data communication. Data transfer rate during the SD mode and SPI mode is faster, uses SPI mode is generally used when the microcontroller of the SD card reader. Different ways to initialize the SD card can operate in SD mode or SPI mode. Here only introduces its SPI mode.

(2)  SPI driven SD card method of
     the SD card SPI communication interface so that it can read and write data through the SPI channel. From the application point of view, the benefits of using the SPI interface is that many own internal microcontroller SPI controller, not only bring the development of convenient, but also to see lower development costs. However, it also has its place, such as loss of the performance benefits of the SD card, to solve this problem, we must use SD way, because it provides more data bandwidth bus. SPI interface is selected at the time of initial power-on when the first write command. The following describes the method of driving the SD card, to achieve only a simple reading and writing sectors.
1) commands and data transmission
1. command to transfer
the SD card itself has a complete command system to achieve the operation. Command format is as follows:

Transmission command using the transmission response mechanism, as follows:

Each command has its own command response format. In response format defines three SPI mode, as shown in the following table:

 

写命令的例程:
//-----------------------------------------------------------------------------------------------
  向SD卡中写入命令,并返回回应的第二个字节
//-----------------------------------------------------------------------------------------------
unsigned char Write_Command_SD(unsigned char *CMD)
{
   unsigned char tmp;
   unsigned char retry=0;
   unsigned char 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(); //read the first byte,ignore it.
   do
   {  //读取后8位
      tmp = Read_Byte_SD();
      retry++;
   }
   while((tmp==0xff)&&(retry<100));
   return(tmp);
}

2) 初始化
SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行后面的各项操作。在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。在初始化成功后,应尽量提高SPI的速率。在刚开始要先发送至少74个时钟信号,这是必须的。在很多读者的实验中,很多是因为疏忽了这一点,而使初始化不成功。随后就是写入两个命令CMD0与CMD1,使SD卡进入SPI模式
           初始化时序图:

 初始化例程:
//--------------------------------------------------------------------------
    初始化SD卡到SPI模式
//--------------------------------------------------------------------------
unsigned char SD_Init()

   unsigned char retry,temp;
   unsigned char i;
   unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
SD_Port_Init(); //初始化驱动端口
  
   Init_Flag=1; //将初始化标志置1

 

   for (i=0;i<0x0f;i++)
   {
      Write_Byte_SD(0xff); //发送至少74个时钟信号
   }
 
   //向SD卡发送CMD0
   retry=0;
   do
   { //为了能够成功写入CMD0,在这里写200次
     temp=Write_Command_SD(CMD);
     retry++;
     if(retry==200)
     { //超过200次
       return(INIT_CMD0_ERROR);//CMD0 Error!
     }
   }
   while(temp!=1);  //回应01h,停止写入
  
   //发送CMD1到SD卡
   CMD[0] = 0x41; //CMD1
   CMD[5] = 0xFF;
   retry=0;
   do
   { //为了能成功写入CMD1,写100次
     temp=Write_Command_SD(CMD);
     retry++;
     if(retry==100)
     { //超过100次
       return(INIT_CMD1_ERROR);//CMD1 Error!
     }
   }
   while(temp!=0);//回应00h停止写入
  
   Init_Flag=0; //初始化完毕,初始化标志清零
  
   SPI_CS=1;  //片选无效
   return(0); //初始化成功
}
3) 读取CID
CID寄存器存储了SD卡的标识码。每一个卡都有唯一的标识码。
CID寄存器长度为128位。它的寄存器结构如下:
 

它的读取时序如下:

与此时序相对应的程序如下:
//------------------------------------------------------------------------------------
    读取SD卡的CID寄存器   16字节   成功返回0
//-------------------------------------------------------------------------------------
unsigned char Read_CID_SD(unsigned char *Buffer)
{
   //读取CID寄存器的命令
   unsigned char CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
   unsigned char temp;
   temp=SD_Read_Block(CMD,Buffer,16); //read 16 bytes
   return(temp);
}

4)读取CSD
CSD(Card-Specific Data)寄存器提供了读写SD卡的一些信息。其中的一些单元可以由用户重新编程。具体的CSD结构如下:

读取CSD 的时序:

相应的程序例程如下:
//-----------------------------------------------------------------------------------------
    读SD卡的CSD寄存器   共16字节    返回0说明读取成功
//-----------------------------------------------------------------------------------------
unsigned char Read_CSD_SD(unsigned char *Buffer)

   //读取CSD寄存器的命令
   unsigned char CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
   unsigned char temp;
   temp=SD_Read_Block(CMD,Buffer,16); //read 16 bytes
   return(temp);
}

 

4) 

读取SD卡信息
综合上面对CID与CSD寄存器的读取,可以知道很多关于SD卡的信息,以下程序可以获取这些信息。如下:
//-----------------------------------------------------------------------------------------------
//返回
//  SD卡的容量,单位为M
//  sector count and multiplier MB are in
u08 == C_SIZE / (2^(9-C_SIZE_MULT))
//  SD卡的名称
//-----------------------------------------------------------------------------------------------
void SD_get_volume_info()
{  
    unsigned char i;
    unsigned char c_temp[5];
    VOLUME_INFO_TYPE SD_volume_Info,*vinf;
    vinf=&SD_volume_Info; //Init the pointoer;
/读取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;
 // 获取multiplier
 vinf->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);
 // get the name of the card
 Read_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; //end flag 
}
         以上程序将信息装载到一个结构体中,这个结构体的定义如下:
typedef struct SD_VOLUME_INFO
{ //SD/SD Card info
  unsigned int  size_MB;
  unsigned char sector_multiply;
  unsigned int  sector_count;
  unsigned char name[6];
} VOLUME_INFO_TYPE;

Guess you like

Origin blog.csdn.net/u010783226/article/details/92065035