1.首先,一定要確定你的卡是好的,我這個(gè)就浪費(fèi)了我一天的時(shí)間,你用筆記本看看是不是能識(shí)別和讀寫(xiě)這個(gè)大卡,不要把小卡拿出來(lái)試試放回到卡套里,因?yàn)槲揖褪强ㄌ讐牧恕?/div>
3.在剛加入這兩個(gè)文件后,我也遇到了一些提示錯(cuò)誤,但是現(xiàn)在都不見(jiàn)了,我重新加入新的沒(méi)有改動(dòng)的這兩個(gè)文件,也不會(huì)提示有問(wèn)題,我是想說(shuō),原廠(chǎng)文件應(yīng)該 是沒(méi)有問(wèn)題的,網(wǎng)上說(shuō)的會(huì)提示的錯(cuò)誤我也不知道為什么會(huì)有,我的非常穩(wěn)定,4bit和25mhz,杠杠的,但是可以給出以下的建議,防止一些錯(cuò)誤。
4.首先是初始化的時(shí)候,網(wǎng)上說(shuō)應(yīng)該在上電之后加入74clk時(shí)鐘,其實(shí)可以不加,只要你上電之后初始化其他東西的時(shí)間足夠,我是沒(méi)有加,也沒(méi)有任何問(wèn)題。
5.然后就是在讀寫(xiě)的時(shí)候可能有人遇到crc校驗(yàn)不正;蛘邲](méi)有檢測(cè)到起始信號(hào),給出以下提示:
-
因?yàn)樽x寫(xiě)塊函數(shù)調(diào)用了DMA的配置函數(shù)SD_LowLevel_DMA_TxConfig和SD_LowLevel_DMA_RxConfig,這兩個(gè)函數(shù)中值得注意的是,SDDMA_InitStructure.DMA_BufferSize = xxx;這里的xxx其實(shí)可以為任意值,因?yàn)楹竺鏁?huì)有一句 DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);這個(gè)是硬件流控制,不論你設(shè)置多少的數(shù),都會(huì)在初始化之后成為0xffff,詳情看dma的硬件流部分。
-
SDIO也有一個(gè)硬件流,勸不要打開(kāi),因?yàn)榇蜷_(kāi)之后會(huì)出現(xiàn)SDIO還需要數(shù)據(jù)的時(shí)候DMA已經(jīng)停止工作了,具體原因不詳。
-
官方給的讀寫(xiě)塊函數(shù),里面最好把DMA的使能還有SDIO的使能放在SDIO_DataInitStructure配置玩之后,安全點(diǎn)。舉例如下,注意顏色部分是改動(dòng)的。
SD_Error SD_WriteBlock(uint8_t *writebuff, uint64_t WriteAddr, uint16_t BlockSize)
{
SD_Error errorstatus = SD_OK;
#if defined (SD_POLLING_MODE)
uint32_t bytestransferred = 0, count = 0, restwords = 0;
uint32_t *tempbuff = (uint32_t *)writebuff;
#endif
TransferError = SD_OK;
TransferEnd = 0;
StopCondition = 0;
SDIO->DCTRL = 0x0;
if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
{
BlockSize = 512;
WriteAddr /= 512;
}
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
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_SET_BLOCKLEN);
if (SD_OK != errorstatus)
{
return(errorstatus);
}
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)WriteAddr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_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_WRITE_SINGLE_BLOCK);
if (errorstatus != SD_OK)
{
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_ToCard;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataConfig(&SDIO_DataInitStructure);
#if defined (SD_POLLING_MODE)
while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
{
if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
{
if ((512 - bytestransferred) < 32)
{
restwords = ((512 - bytestransferred) % 4 == 0) ? ((512 - bytestransferred) / 4) : (( 512 - bytestransferred) / 4 + 1);
for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
{
SDIO_WriteData(*tempbuff);
}
}
else
{
for (count = 0; count < 8; count++)
{
SDIO_WriteData(*(tempbuff + count));
}
tempbuff += 8;
bytestransferred += 32;
}
}
}
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_TXUNDERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
errorstatus = SD_TX_UNDERRUN;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
errorstatus = SD_START_BIT_ERR;
return(errorstatus);
}
#elif defined (SD_DMA_MODE)
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, BlockSize);
SDIO_DMACmd(ENABLE);
#endif
return(errorstatus);
}