To learn here, you must first understand the basic information of SD card:
The SD card protocol has too many parts and is quite complicated. The recommended document is: "Simplified_Physical_Layer_Spec.pdf". Its main complexity lies in the numerous commands. There are 64 commands in total. You can check the document for what each command represents.
Most of the time here you just need to be familiar with the functions and call the library directly, but you still need to read each function. There will be examples of the use of specific functions later, which will be supplemented at that time.
The SD card library provided by ARM is generally used in our code, but there is a problem in the library, SD_Error SD_ReadBlock() is missing code: (marked, can be directly replaced)
SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize)
{
SD_Error errorstatus = SD_OK;
#if defined (SD_POLLING_MODE)
uint32_t count = 0, *tempbuff = (uint32_t *)readbuff;
#endif
TransferError = SD_OK;
TransferEnd = 0; //Set the transfer end flag, set to 1 in the interrupt service
StopCondition = 0; //How to use it?
SDIO->DCTRL = 0x0;
if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
{
BlockSize = 512;
ReadAddr /= 512;
}
/*******************add, without this section, it is easy to get stuck in DMA detection****************************************/
/* Set Block Size for Card,cmd16,
* If it is a sdsc card, it can be used to set the block size.
* If it is an SDHC card, the block size is 512 bytes and is not affected by cmd16
*/
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r1
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);
if (SD_OK != errorstatus)
{
return(errorstatus);
}
/*********************************************************************************/
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataConfig(&SDIO_DataInitStructure);
/*!< Send CMD17 READ_SINGLE_BLOCK */
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
#if defined (SD_POLLING_MODE)
/*!< In case of single block transfer, no need of stop transfer at all.*/
/*!< Polling mode */
while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))
{
if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
{
for (count = 0; count < 8; count++)
{
*(tempbuff + count) = SDIO_ReadData();
}
tempbuff += 8;
}
}
if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
errorstatus = SD_DATA_TIMEOUT;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
errorstatus = SD_DATA_CRC_FAIL;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
errorstatus = SD_RX_OVERRUN;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
errorstatus = SD_START_BIT_ERR;
return(errorstatus);
}
while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
{
*tempbuff = SDIO_ReadData();
tempbuff++;
}
/*!< Clear all the static flags */
SDIO_ClearFlag(SDIO_STATIC_FLAGS);
#elif defined (SD_DMA_MODE)
SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);
SDIO_DMACmd(ENABLE);
SD_DMA_RxConfig((uint32_t *)readbuff, BlockSize);
#endif
return(errorstatus);
}
Previous article:Some thoughts and conclusions on the communication between STM32 and SD card
Next article:Summary of the process of writing serial port program for stm32f407
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- 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!
- 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
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Wireless Wi-Fi product coverage is not good, Wi-Fi 6 iFEM can solve it
- Basic knowledge before learning FPGA
- recruitment
- [New version of Zhongke Bluexun AB32VG1 RISC-V development board] - 8: PWM
- TI Real-Time Kernel SYSBIOS Boot Process
- LM2576 fault problem
- Good luck on the start of work, grab the building and get a gift! Prediction: Hot keywords for electronics in 2021
- Application of power amplifier in mechanical output experiment of piezoelectric actuator design
- EEWORLD University ---- Find products and add to shopping cart quickly
- BK3432 SDK Development and Use GuideBK3432 SDK Development and Use Guide