本帖最后由 飛饵 于 2019-2-13 18:29 编辑
SD卡操作是用ST官方的SDIO例程。用fatfs时发现 f_open()老返回no_filesystem错误,debug到最后发现SD卡的那个单块读函数 SD_ReadBlock()读的数据是错的,单独测试这个函数也是错的,没仔细研究过这个函数原理,所以不懂怎么解决。
不过那个多块读函数就没问题,虽然fatfs接口里可以用多块读代替,但有没有人知道 SD_ReadBlock()的bug怎么解决?
还有个现象,单独测试 SD_ReadBlock()时,如果在前面先执行一遍 SD_ReadMultiBlocks(),接下来 SD_ReadBlock()读出来的数据又对了。但是单独执行的数据就一直错的
贴上代码
[mw_shl_code=c,true]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;
StopCondition = 0;
SDIO->DCTRL = 0x0;
if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
{
BlockSize = 512;
ReadAddr /= 512;
}
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_ITConfig(SDIO_IT_RXOVERR|SDIO_IT_DTIMEOUT|SDIO_IT_DCRCFAIL|SDIO_IT_DATAEND, ENABLE);//使用这句,防止传输错误造成卡死
SDIO_DMACmd(ENABLE);
SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, BlockSize);
#endif
return(errorstatus);
}[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
那没办法了。代码是官方例程没修改过的。
一周热门 更多>