The picture below shows the SD card part of the Wanli board
SD_PWR is connected to PD10 through a control
P-Channel 2.5-V (GS) MOSFET controls the power supply of the SD card
=====================================================================
SPI mode read and write SD card
SD card initialization process:
1. Initialize the SPI interface of STM32 to use low-speed mode
2. Delay at least 74clock
3. Send CMD0, need to return 0x01, enter the Idle state
4. Loop and send CMD55+ACMD41 until it returns 0x00, enter the Ready state
5. Set the read and write block size to 512byte
5. Set the SPI of STM32 to high-speed mode
The process of reading a block
1. Send CMD17 (single block) or CMD18 (multiple blocks) read command, return 0x00
2. Receive data start token 0xfe + formal data 512Bytes + CRC check 2Bytes
The process of writing a block
1. Send CMD24 (single block) or CMD25 (multiple blocks) write command, return 0x00
2. Send data start token 0xfe + formal data 512Bytes + CRC check 2Bytes
/*******************************************************************************
* Function Name : SD_MMC_SPI_Init
* Description : SD_MMC_SPI_Init
* Input : None
* Output : None
* Return : zero init success, non-zero init error
*******************************************************************************/
u8 SD_MMC_SPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_SD_MMC_SPI_CS, ENABLE);
/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure SD_MMC_SPI_CS */
GPIO_InitStructure.GPIO_Pin = SD_MMC_SPI_CS_Pin_CS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SD_MMC_SPI_CS, &GPIO_InitStructure);
//////////////////////////////////////////////////////////////////////////////
/* initialize SPI with lowest frequency */
SD_MMC_Low_Speed();
/* card needs 74 cycles minimum to start up */
for(u8 i = 0; i < 10; ++i)
{
/* wait 8 clock cycles */
SD_MMC_ReadWrite_Byte(0x00);
}
/* address card */
SD_MMC_SPI_SELECT();
/* reset card */
u8 response;
for(u16 i = 0; ; ++i)
{
response = SD_MMC_Send_Command(CMD_GO_IDLE_STATE , 0 );
if( response == 0x01 )
break;
if(i == 0x1ff)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}
/* wait for card to get ready */
for(u16 i = 0; ; ++i)
{
response = SD_MMC_Send_Command(CMD_SEND_OP_COND, 0);
if(!(response & (1 << R1_IDLE_STATE)))
break;
if(i == 0x7fff)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}
/* set block size to 512 bytes */
if(SD_MMC_Send_Command(CMD_SET_BLOCKLEN, 512))
{
SD_MMC_SPI_DESELECT();
return 1;
}
/* deaddress card */
SD_MMC_SPI_DESELECT();
/* switch to highest SPI frequency possible */
SD_MMC_High_Speed();
return 0;
//////////////////////////////////////////////////////////////////////////////
}
/*******************************************************************************
* Function Name : SD_MMC_Read_Single_Block
* Description : SD_MMC_Read_Single_Block
* Input : sector number and buffer data point
* Output : None
* Return : zero success, non-zero error
*******************************************************************************/
u8 SD_MMC_Read_Single_Block(u32 sector, u8* buffer)
{
u8 Response;
u16 i;
u16 Retry = 0;
//读命令 send read command
Response = SD_MMC_Send_Command(CMD_READ_SINGLE_BLOCK, sector<<9);
if(Response != 0x00)
return Response;
SD_MMC_SPI_SELECT();
// start byte 0xfe
while(SD_MMC_ReadWrite_Byte(0xff) != 0xfe)
{
if(++Retry > 0xfffe)
{
SD_MMC_SPI_DESELECT();
return 1; //timeout
}
}
for(i = 0; i < 512; ++i)
{
//Read 512 data
*buffer++ = SD_MMC_ReadWrite_Byte(0xff);
}
SD_MMC_ReadWrite_Byte(0xff); //伪crc
SD_MMC_ReadWrite_Byte(0xff); //伪crc
SD_MMC_SPI_DESELECT();
SD_MMC_ReadWrite_Byte(0xff); // extra 8 CLK
return 0;
}
/*******************************************************************************
* Function Name : SD_MMC_Write_Single_Block
* Description : SD_MMC_Write_Single_Block
* Input : sector number and buffer data point
* Output : None
* Return : zero success, non-zero error.
*******************************************************************************/
u8 SD_MMC_Write_Single_Block(u32 sector, u8* buffer)
{
u8 Response;
u16 i;
u16 retry=0;
//写命令 send write command
Response = SD_MMC_Send_Command(CMD_WRITE_SINGLE_BLOCK, sector<<9);
if(Response != 0x00)
return Response;
SD_MMC_SPI_SELECT();
SD_MMC_ReadWrite_Byte(0xff);
SD_MMC_ReadWrite_Byte(0xff);
SD_MMC_ReadWrite_Byte(0xff);
//发开始符 start byte 0xfe
SD_MMC_ReadWrite_Byte(0xfe);
//送512字节数据 send 512 bytes data
for(i=0; i<512; i++)
{
SD_MMC_ReadWrite_Byte(*buffer++);
}
SD_MMC_ReadWrite_Byte(0xff); //dummy crc
SD_MMC_ReadWrite_Byte(0xff); //dummy crc
Response = SD_MMC_ReadWrite_Byte(0xff);
//等待是否成功 judge if it successful
if( (Response&0x1f) != 0x05)
{
SD_MMC_SPI_DESELECT();
return Response;
}
//等待操作完 wait no busy
while(SD_MMC_ReadWrite_Byte(0xff) != 0x00)
{
if(retry++ > 0xfffe)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}
SD_MMC_SPI_DESELECT();
SD_MMC_ReadWrite_Byte(0xff);// extra 8 CLK
return 0;
}
if( SD_MMC_SPI_Init() ==1)
printf(" _SD_MMC Initialization ERROR\r\n");
else
{
printf(" _SD_MMC Initialization OK\r\n");
//memset(buffer,0,512);
//Read the contents of a sector. Here, sector 0 is read.
SD_MMC_Read_Single_Block( 0 , buffer );
Uart1_PutString( buffer , 512 );
}
Previous article:6 steps to teach you how to add printf function in STM32 program
Next article:STM32 DMA learning
Recommended ReadingLatest update time:2024-11-17 02:42
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- Rambus Launches Industry's First HBM 4 Controller IP: What Are the Technical Details Behind It?
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- Analysis of power batteries in the first quarter of 2021
- Using STM32L452 to drive STTS751 through C-Driver-MEMS
- [RTT & Renesas high-performance CPK-RA6M4] 1. Hardware appreciation and RT-Thread development environment construction
- CB140-6G2C core board pin definition solution
- How to achieve PLC remote control through 4G network?
- How does USB 3.0 electrostatic protection maintain signal integrity?
- does not name a type
- Let's talk about millimeter wave: What is millimeter wave? What can millimeter wave do?
- Request a switching power supply voltage regulator circuit principle explanation
- EEWORLD University ---- Live playback: The most important component of the analog world - Signal chain and power supply: Sensor