×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-08-28 发布时间:
|

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


https://prod-1251541497.cos.ap-guangzhou.myqcloud.com/zixun_pc/zixunimg/img2/news-uploadfile-2018-1226-20181226041927610.jpghttps://prod-1251541497.cos.ap-guangzhou.myqcloud.com/zixun_pc/zixunimg/img2/news-uploadfile-2018-1226-20181226041927610.jpg



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);

}

关键字:STM32  SDIO  SD卡读取 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析