An in-depth understanding of the basic principles and internal structure of the SD card

Source: Internet
Author: User

1. Introduction:
Secure Digital Memory Card is a new type of memory device designed to meet security, capacity, performance, and use environment requirements, the SD card can work in two modes: SD mode and SPI mode. The system adopts the SPI mode. This section only briefly introduces how the stm32 processor reads and writes SD cards in SPI mode. If you want to learn more about SD cards, refer to relevant materials.
Shows the internal structure and pins of the SD card:

 


SD card internal Diagram

2. SD card pins:


SD card image. jpg

3. In spi mode, the names of SD pins are as follows:
SD card:


In spi mode, the SD pins are named. jpg.

Note: SD has two modes: SD mode and SPI mode. The Pin is defined as follows:
(A), SD Mode 1, CD/data3 2, CMD 3, vss1 4, VDD 5, CLK 6, vss2 7, data0 8, data1 9, data2
(B), SPI Mode 1, CS 2, di 3, VSS 4, VDD 5, sclk 6, vss2 7, do 8, fulfill 9, and fulfill

The main pins and functions of the SD card are:
CLK: clock signal. One command or data bit is transmitted in each clock cycle. The frequency can be between 0 and 0 ~ The bus manager of the SD card is free to generate 0 ~ 25 MHz frequency;
CMD: bidirectional commands and reply lines. commands start from the host to the card operation. commands can be from the host to the single-card addressing, or to all cards; the reply is the answer to the previous command. The reply can come from a single card or all cards;
Dat0 ~ 3: data line. data can be transmitted from the card to the host or from the host to the card.
The SD card uses commands to control the read/write operations on the SD card. You can perform read and write operations on multiple or one block according to the command. In spi mode, the command consists of 6 bytes, with the highest position in the front. The SD card command format is shown in Table 1. For more information about the parameters, see SD card specifications.

4. microSD card pins:


MicroSD card pins. jpg

5. microSD card pin Name:


MicroSD card pin name. jpg

The SD card and the microSD card are only encapsulated differently. The microSD card is smaller and the size is similar to that of a SIM card, but the protocol is the same as that of the SD card.
Generally, when we use a single-chip microcomputer to operate the SD card, we do not need to process the FAT partition table information, for the following reasons:
1) to operate a FAT partition table, you need to increase the amount of program code and increase the consumption of SRAM. For portable applications, the code size and the amount of SRAM occupied are crucial.
2) even if we do not know anything about the FAT partition table, we can write data to the SD card, which means that using fat is just a weakness for data storage applications.
3) It takes a lot of experience and time to understand the FAT partition table, which is not worth the candle for our embedded software developers.
4) the SD card supports two modes: SD mode and SPI mode. You do not need to know fat when operating SD data in the SPI mode, at this time, the SD card is actually a large, fast, convenient, and variable-volume external memory.
Based on the above reasons, the general operation on the SD card only needs to understand the SPI communication, and now most of the single-chip microcomputer has SPI interface, the operation of the SD card is easy.

The following is the circuit diagram used for SD card testing:


Circuit Diagram for SD card test. jpg

Sd_cs/SD pins connected to single-chip microcomputer. SD cards can be operated only when sd_cs/is set to low-power.
Mosi is connected to the MoSi pin (SPI data input) of the mcu spi bus. The MCU reads the data in the SD card from this pin.
Miso connects the miso pin (SPI data output) of the single-chip microcomputer SPI bus. The single-chip microcomputer writes data to the SD card through this pin.
Sck connecting mcu spi bus sck (SPI clock)
The SD pin is actually connected to Gnd in the SD card. When the SD socket is not inserted with the SD card, the single-chip machine can read the high level from this pin (provided that the single-chip microcomputer is used to pull the input internally, or add an external pull-up resistor). Once the SD card is inserted, the pin becomes low. This function is used to detect whether the SD card is inserted.
Rsv1 and rsv2 are feature pins that do not need to be operated.
The connection of the microSD card is similar to that of the SD card, but the microSD card has only one Gnd pin less than the SD card. Therefore, you cannot use this plug-in card detection method, in fact, many SD card/microSD card sockets now have insertion detection pins. Of course, the price is also more expensive.
By the way, a general SD card socket can cost a maximum of five yuan.

SPI Command Format

Byte 1 Byte2-5 Byte 6
7 6 5 0 31 0 7 0
0 1 Command Command argument CRC 1

The following is a simple program for reading and writing SD card. The Program is based on the ATmega128 single-chip microcomputer. For other single-chip microcomputer of Atmega, you only need to change the pins to use the program.
SD. h
//************************************** ****************************
// The ports occupied by each SPI line
# Define sd_ss pb6
# Define sd_sck PB1
# Define sd_mosi PBS
# Define sd_miso PB3
//************************************** ****************************

# Define sd_ddr ddrb
# Define sd_port portb
# Define sd_pin Pinb

# Define sd_ss_h sd_port | = (1 <
# Define sdss_l sd_port & = ~ (1 <
# Define sd_sck_h sd_port | = (1 <
# Define sd_sck_l sd_port & = ~ (1 <
# Define sd_mosi_h sd_port | = (1 <
# Define sd_mosi_l sd_port & = ~ (1 <

# Define sd_miso_in (sd_pin & (1 <
//-------------------------------------------------------------
// Error code
//-------------------------------------------------------------
# Define init_1_0_error 0xff
# Define init_00000000error 0xfe
# Define write_block_error 0xfd
# Define read_block_error 0xfc
# Define true 0x01
//-------------------------------------------------------------
// MMC/SD command (the command number starts from 40 and only lists basic commands, not all of which are used)
//-------------------------------------------------------------
# Define sd_reset 0x40 + 0
# Define sd_init 0x40 + 1
# Define sd_read_csd 0x40 + 9
# Define sd_read_cid 0x40 + 10
# Define sd_stop_transmission 0x40 + 12
# Define sd_send_status 0x40 + 13
# Define sd_set_blocklen 0x40 + 16
# Define sd_read_block 0x40 + 17
# Define sd_read_multi_block 0x40 + 18
# Define sd_write_block 0x40 + 24
# Define sd_write_multi_block 0x40 + 25

// Chip selection (MMC/SD-card invalid)
# Define sd_disable () sd_ss_h
// Select an option (MMC/SD-card active)
# Define sd_enable () sd_ss_l

Sd_test.c
//************************************** **************************************** **********/
// ICC-AVR Application Builder: 03-5-20 8:39:11
// Target: m128
// Crystal: 3.6864 MHz

# Include
# Include
# Include 'sd. H'
Void uart0_init (void );
Void putchar (unsigned char content );
Void putstr (unsigned char * s );
Void sd_port_init (void );
Unsigned char sd_init (void );
Unsigned char sd_write_sector (unsigned long ADDR, unsigned char * buffer );
Unsigned char sd_read_sector (unsigned long ADDR, unsigned char * buffer );
Unsigned char spi_transferbyte (unsigned char byte );
Unsigned char write_command_sd (unsigned char cmd, unsigned Long Address );
Unsigned long sd_find (void );
//************************************** ************************************
// Serial port debugging program
//************************************** ************************************
Void uart0_init (void)
{
Ucsr0b = 0x00; // disable while setting baud rate
Ucsr0a = 0x00;
Ucsr0c = 0x06; // 00000110 uart0 is set to asynchronous mode, no parity check, 1-bit stop bit, 8-Bit Data bit
Ubrr0l = 0x17; // set baud rate Lo
Ubrr0h = 0x00; // set baud rate hi to set the uart0 port communication rate to 9600
Ucsr0b = 0x18;
}
Void putchar (unsigned char content)
{

While (! (Ucsr0a & (1 <udre0);/* determines whether the last sending is complete */
Udr0 = content;/* send data */

}
Void putstr (unsigned char * s)
{

While (* s)
{
Putchar (* s );
S ++;
}

}

//************************************** **************************************
// Port Initialization
Void sd_port_init (void)
//************************************** **************************************
{
Sd_port | = (1 <
Sd_ddr | = (1 <
Sd_ddr & = ~ (1 <
}

//************************************** **************************************
// Initialize the MMC/SD card to the SPI Mode
Unsigned char sd_init (void)
//************************************** **************************************
{
Unsigned char retry, temp;
Unsigned char I;

Spcr = 0x53; // set SPI to 128 for frequency division and initialize at a low speed.
Spsr = 0x00;

For (I = 0; I <0x0f; I ++)
{
Spi_transferbyte (0xff); // delay more than 74 clocks
}

Sd_enable (); // open an slice

Spi_transferbyte (sd_reset); // send the reset command
Spi_transferbyte (0x00 );
Spi_transferbyte (0x00 );
Spi_transferbyte (0x00 );
Spi_transferbyte (0x00 );
Spi_transferbyte (0x95 );

Spi_transferbyte (0xff );
Spi_transferbyte (0xff );

Retry = 0;
Do {
Temp = "write" _ command_sd (sd_init, 0); // send the initialization command
Retry ++;
If (retry = 100) // retry 100 times
{
Sd_disable (); // select the Parameter

Return (init_failureerror); // If the retry fails for 100 times, the error code is returned.

}
} While (temp! = 0 );

Msd_disable (); // Filter

Spcr = 0x50; // set the SPI to a 2-byte frequency. High-speed read/write
Spsr = 0x01;

Return (true); // return success
}

//************************************** **************************************
// Send a command to MMC/SD card
// Return: returns the 2nd bytes of the MMC/SD card response to the command, which is successfully judged as a command.
Unsigned char write_command_sd (unsigned char cmd, unsigned long address)
//************************************** **************************************
{
Unsigned char TMP;
Unsigned char retry = "0 ";

Sd_disable ();
Spi_transferbyte (0xff );

Sd_enable ();

Spi_transferbyte (CMD); // shift the 32-bit address as the address byte
Spi_transferbyte (address> 24 );
Spi_transferbyte (address> 16 );
Spi_transferbyte (address> 8 );
Spi_transferbyte (Address );
Spi_transferbyte (0xff );

Spi_transferbyte (0xff );

Do {
TMP = spi_transferbyte (0xff); // send eight clocks to accept the last byte
Retry ++;
} While (TMP = 0xff) & (retry <8 ));
Return (TMP );

}

//************************************** **************************************
// Write a sector (512 bytes) to MMC/SD-card
// Returns true if the write is complete.
Unsigned char sd_write_sector (unsigned long ADDR, unsigned char * buffer)
//************************************** **************************************
{
Unsigned char temp;
Unsigned int I;

Spi_transferbyte (0xff); // eight clock delays
Sd_enable (); // open an slice

Temp = write_command_mmc (mmc_write_block, ADDR <9); // send the write Sector Command
If (temp! = 0x00)
{
Sd_disable ();
Return (temp );
}

Spi_transferbyte (0xff );
Spi_transferbyte (0xff );
Spi_transferbyte (0xfe );

For (I = 0; I <512; I ++)
{
Spi_transferbyte (* buffer ++); // send 512 bytes of data
}

// CRC-byte
Spi_transferbyte (0xff); // dummy CRC
Spi_transferbyte (0xff); // CRC code

Temp = spi_transferbyte (0xff); // read the SD card running response
If (temp & 0x1f )! = 0x05) // if the last 4 digits are 0101, the operation is successful. Otherwise, the operation fails.
{
Sd_disable ();

Return (write_block_error); // return an error
}

While (spi_transferbyte (0xff )! = 0xff );

Sd_disable ();
Return (true); // return success
}
//************************************** **************************************
// Read 512 bytes from MMC/SD-card
// Returns true if the call is successful.
Unsigned char sd_read_sector (unsigned long ADDR, unsigned char * buffer)
//************************************** **************************************
{
Unsigned char temp;
Unsigned int I;
Unsigned char data;

Spi_transferbyte (0xff );

Mmc_enable ();

Temp = write_command_sd (sd_read_block, ADDR <9); // send the read Sector Command

If (temp! = 0x00)
{
Sd_disable ();

Return (read_block_error); // return the error code.
}

While (spi_transferbyte (0xff )! = 0xfe );

For (I = 0; I <512; I ++)
{
Data = spi_transferbyte (0xff); // store data

* Buffer ++ = data;

}

Spi_transferbyte (0xff); // read the CRC code
Spi_transferbyte (0xff); // read the CRC code

Sd_disable ();

Return (true); // return success
}
//************************************** ************************************
// Search for the data start mark (default datastart) and delete it as needed
//************************************** ************************************
Unsigned long sd_find (void)
{
Unsigned long TMP = "400 ";
Unsigned char data [512];

Do
{
Sd_read_sector (TMP, data); // start from 0 sectors
TMP ++; // search for datastart

} While (! (Data [0] = 'D') & (data [1] = 'A') & (data [2] = 'T ') & (data [3] = 'A') & (data [4] = 's') & (data [5] = 'T ') & (data [6] = 'A') & (data [7] = 'R ') & (data [8] = 'T ')));
Return TMP; // return the next sector of the Start flag.
}
//************************************** ************************************
// Send a byte
//************************************** ************************************
Unsigned char spi_transferbyte (unsigned char byte)
{
SPDR = byte;
While (! (Spsr & 0x80); // check whether the line is idle
Return SPDR;
}

//************************************** ************************************
// Main program example
//************************************** ************************************
Void main (void)
{
Unsigned long temp;
Unsigned char data [512];
Unsigned char data2 [512] = {'sssssssssssssssssssssss '};
Unsigned char comm1 [] = {'/R/nhello world/R/N '};
Unsigned char comm2 [] = {'/R/nsd_init OK/R/N '};
Uart0_init ();
Sd_port_init (); // port Initialization
If (sd_init () = 0x01)
{// Initialize the SD card and read the returned value
Putstr (comm2 );
}
Temp = "SD" _ Find (); // find the Start mark of datastart data and return the address of the next sector
Sd_read_sector (1001, data); // reads 512 bytes of data from the temp address, and saves 512 bytes of data to the data array.
Putstr (data );
Sd_write_sector (temp, data2); // write 512 bytes of data in the data2 array to the temp sector
}

The test procedure is very simple, just a test of reading and writing SD cards.

Precautions for SD card.
1. Whether we like or not, the minimum unit of data read/write on the SD card is 1 sector, that is, 512 bytes.
2. the SPI bus connected to the SD card and the single-chip microcomputer should not be too long and should be as short as possible. The advantage is that the speed is faster and error-prone.
3. Although we do not care about the FAT file table, we still need to care about the storage structure of the SD card, if we don't want to use a PC to read data stored on the SD card, we don't have to worry about the SD storage structure. However, as a large-capacity removable storage device, it is a big pity that you cannot use a PC to read data. The method to solve this problem is as follows:
3-1. Because I do not know the complex structure of fat, my program cannot create files, delete files, create directories, and so on according to the features of the fat table.
3-2. Although our single-chip microcomputer cannot create files, but the PC can create files! So I used a PC to format the SD card, and then created a large file on the SD card. For example, I created a M file on my m SD card. Note that when using the Windows File Creation function, you cannot specify the size of the file to be created. An empty file is the length of 0 bytes, we need a fixed-length file, so I wrote a small software with VC. This software can create a m-length empty file for me. Remember, this is very important: A fixed-length empty file
3-3. Although we have created a file on the SD card, we do not know the fat table, so we do not know where the file is located, do not think it will start at 0 bytes. To locate the start position of this file, we can write a few characters at the beginning of the empty file that we created, for example, if "datastart" is written in my program, what we need to do next is to find these special characters for one slice and one slice. This is a stupid method, but it is the simplest and most intuitive method. This method has two disadvantages: A. If the file is created behind the entire SD card, it will take a long time to find the file. B. if a file also contains the special string we defined, it would be messy! Fortunately, the SD cards we use are generally dedicated and cannot be used for other applications, such as copying files from the company to go home. This ensures the simplicity of the files on this SD card, that is, only the file we need does not exist in other files, and the file will certainly start from one of the sectors starting from the SD card. In this case, finding this string is not that slow! ^_^. However, we recommend that you use Windows to fully format the SD card.
3-4. Once we find the starting position of the file to be written (which is generally expressed as a sector code), we can write data to the next sector of the starting sector.
4. OK. It looks very simple! With this storage method, what else do we need the IIC interface's EEPROM?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.