STM32笔记--SDIO(SD卡读取)

匿名 (未验证) 提交于 2019-12-03 00:30:01

学习这里首先要了解一下SD卡基本资料:


SD卡的协议部分太多,也比较复杂,建议资料:《Simplified_Physical_Layer_Spec.pdf》其主要复杂在繁多的命令,一共有64个命令,各个命令代表什么可查资料。



关于这里大部分都是熟悉函数然后直接调用库就行,但还是需要每个函数都去读一下的,后面会有具体函数的使用实例,到时候再补充。

我们代码中一般用到的是ARM官方给的SD卡的库,但是库中存在问题,SD_Error SD_ReadBlock()缺少代码:(有标注,可直接替换)

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;	 //传输结束标置位,在中断服务置1   StopCondition = 0;  //怎么用的?      SDIO->DCTRL = 0x0;       if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)   {     BlockSize = 512;     ReadAddr /= 512;   }   /*******************add,没有这一段容易卡死在DMA检测中*************************************/   /* Set Block Size for Card,cmd16, 	 * 若是sdsc卡,可以用来设置块大小, 	 * 若是sdhc卡,块大小为512字节,不受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); }



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!