GD32F207 操作SD卡

[复制链接]
2215|28
 楼主| gaoke231 发表于 2020-3-31 23:14 | 显示全部楼层
检查SD可卡是不是出于运行状态
  1. static SD_Err IsCardProgramming(uint8_t *pstatus)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     __IO uint32_t respR1 = 0, status = 0;

  5.     /* CMD13 to polling the state of the card */
  6.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
  7.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  8.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  9.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  10.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  11.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  12.     status = SDIO->STR;
  13.     while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CMDTMOUT)))
  14.     {
  15.         status = SDIO->STR;
  16.     }

  17.     if (status & SDIO_FLAG_CMDTMOUT)
  18.     {
  19.         Status = SD_CMD_RSP_TIMEOUT;
  20.         SDIO_ClearBitState(SDIO_FLAG_CMDTMOUT);
  21.         return(Status);
  22.     }
  23.     else if (status & SDIO_FLAG_CCRCFAIL)
  24.     {
  25.         Status = SD_CMD_CRC_FAIL;
  26.         SDIO_ClearBitState(SDIO_FLAG_CCRCFAIL);
  27.         return(Status);
  28.     }

  29.     status = (uint32_t)SDIO_GetCMDResponse();

  30.     /* Check response received is of desired command */
  31.     if (status != SDIO_SEND_STATUS)
  32.     {
  33.         Status = SD_ILLEGAL_CMD;
  34.         return(Status);
  35.     }

  36.     /* Clear all the static flags */
  37.     SDIO_ClearBitState(SDIO_STATIC_FLAGS);


  38.     /* We have received response, retrieve it for analysis  */
  39.     respR1 = SDIO_GetResponse(SDIO_RESP1);

  40.     /* Find out card status */
  41.     *pstatus = (uint8_t) ((respR1 >> 9) & 0x0000000F);

  42.     if ((respR1 & SD_R1_ERRORBITS) == SD_ALLZERO)
  43.     {
  44.         return(Status);
  45.     }

  46.     if (respR1 & SD_R1_ADDR_OUT_OF_RANGE)
  47.     {
  48.         return(SD_ADDR_OUT_OF_RANGE);
  49.     }

  50.     if (respR1 & SD_R1_ADDR_MISALIGNED)
  51.     {
  52.         return(SD_ADDR_MISALIGNED);
  53.     }

  54.     if (respR1 & SD_R1_BLOCK_LEN_ERR)
  55.     {
  56.         return(SD_BLOCK_LEN_ERR);
  57.     }

  58.     if (respR1 & SD_R1_ERASE_SEQ_ERR)
  59.     {
  60.         return(SD_ERASE_SEQ_ERR);
  61.     }

  62.     if (respR1 & SD_R1_BAD_ERASE_PARAM)
  63.     {
  64.         return(SD_BAD_ERASE_PARAM);
  65.     }

  66.     if (respR1 & SD_R1_WRITE_PROT_VIOLATION)
  67.     {
  68.         return(SD_WRITE_PROT_VIOLATION);
  69.     }

  70.     if (respR1 & SD_R1_LOCK_UNLOCK_FAILED)
  71.     {
  72.         return(SD_LOCK_UNLOCK_FAILED);
  73.     }

  74.     if (respR1 & SD_R1_COM_CRC_FAILED)
  75.     {
  76.         return(SD_COM_CRC_FAILED);
  77.     }

  78.     if (respR1 & SD_R1_ILLEGAL_CMD)
  79.     {
  80.         return(SD_ILLEGAL_CMD);
  81.     }

  82.     if (respR1 & SD_R1_CARD_ECC_FAILED)
  83.     {
  84.         return(SD_CARD_ECC_FAILED);
  85.     }

  86.     if (respR1 & SD_R1_CC_ERROR)
  87.     {
  88.         return(SD_CC_ERROR);
  89.     }

  90.     if (respR1 & SD_R1_GENERAL_UNKNOWN_ERROR)
  91.     {
  92.         return(SD_GENERAL_UNKNOWN_ERROR);
  93.     }

  94.     if (respR1 & SD_R1_STREAM_READ_UNDERRUN)
  95.     {
  96.         return(SD_STREAM_READ_UNDERRUN);
  97.     }

  98.     if (respR1 & SD_R1_STREAM_WRITE_OVERRUN)
  99.     {
  100.         return(SD_STREAM_WRITE_OVERRUN);
  101.     }

  102.     if (respR1 & SD_R1_CID_CSD_OVERWRIETE)
  103.     {
  104.         return(SD_CID_CSD_OVERWRITE);
  105.     }

  106.     if (respR1 & SD_R1_WP_ERASE_SKIP)
  107.     {
  108.         return(SD_WP_ERASE_SKIP);
  109.     }

  110.     if (respR1 & SD_R1_CARD_ECC_DISABLED)
  111.     {
  112.         return(SD_CARD_ECC_DISABLED);
  113.     }

  114.     if (respR1 & SD_R1_ERASE_RESET)
  115.     {
  116.         return(SD_ERASE_RESET);
  117.     }

  118.     if (respR1 & SD_R1_AKE_SEQ_ERROR)
  119.     {
  120.         return(SD_AKE_SEQ_ERROR);
  121.     }

  122.     return(Status);
  123. }


 楼主| gaoke231 发表于 2020-3-31 23:15 | 显示全部楼层
初始化SD卡的GPIO
  1. static void GPIO_Configuration(void)
  2. {
  3.     GPIO_InitPara  GPIO_InitStructure;

  4.     /* Enable GPIOC and GPIOD clock */
  5.     RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOC | RCC_APB2PERIPH_GPIOD, ENABLE);

  6.     /* Configure relative ports(PC8, PC9, PC10, PC11, PC12: D0, D1, D2, D3, CLK pin) */
  7.     GPIO_InitStructure.GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
  8.     GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
  9.     GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
  10.     GPIO_Init(GPIOC, &GPIO_InitStructure);

  11.     /* Configure PD2(CMD line) */
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_PIN_2;
  13.     GPIO_Init(GPIOD, &GPIO_InitStructure);
  14. }


 楼主| gaoke231 发表于 2020-3-31 23:16 | 显示全部楼层
初始化DMA 作为SDIO传输
  1. static void DMA_TxConfiguration(uint32_t *BufferSRC, uint32_t BufferSize)
  2. {
  3.     DMA_InitPara DMA_InitStructure;

  4.     DMA_ClearBitState(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);

  5.     /* DMA2 Channel4 disable */
  6.     DMA_Enable(DMA2_CHANNEL4, DISABLE);

  7.     /* DMA2 Channel4 Config */
  8.     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDR;
  9.     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferSRC;
  10.     DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
  11.     DMA_InitStructure.DMA_BufferSize = BufferSize / 4;
  12.     DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
  13.     DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
  14.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_WORD;
  15.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_WORD;
  16.     DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
  17.     DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
  18.     DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
  19.     DMA_Init(DMA2_CHANNEL4, &DMA_InitStructure);

  20.     /* DMA2 Channel4 enable */
  21.     DMA_Enable(DMA2_CHANNEL4, ENABLE);

  22. }


 楼主| gaoke231 发表于 2020-3-31 23:17 | 显示全部楼层
SD卡上锁
  1. SD_Err SD_Lock_Unlock(uint8_t lockstate)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     u8 cardstate = 0;
  5.     u32 pwd1,pwd2,cardstatus,timeout;

  6.     /* Check if the card command class supports Lock/Unlock command */
  7.     if ((SD_CCC_LOCK_UNLOCK&SDIOInfo.SD_csd.CardComdClasses) == 0)
  8.     {
  9.         Status = SD_REQUEST_NOT_APPLICABLE;
  10.         return(Status);
  11.     }
  12.     /* PWD pattern */
  13.     pwd1 = (0x01020600|lockstate);
  14.     pwd2 = 0x03040506;

  15.     /* Clear all DSM configuration */
  16.     SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
  17.     SDIO_DataInitStructure.SDIO_DataLength = 0;
  18.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
  19.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  20.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  21.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
  22.     SDIO_DataConfig(&SDIO_DataInitStructure);
  23.     SDIO_DMA_Enable(DISABLE);

  24.     /* CMD16 Set Block Size for Card */
  25.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) 8;
  26.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
  27.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  28.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  29.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  30.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  31.     /* Check CMD errors */
  32.     Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
  33.     if (Status != SD_OK)
  34.     {
  35.         return(Status);
  36.     }

  37.     cardstatus = SDIO_GetResponse(SDIO_RESP1);

  38.     /* Wait till card is ready for data writing */
  39.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  40.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  41.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  42.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  43.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  44.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  45.     Status = Check_Err_R1(SDIO_SEND_STATUS);

  46.     if (Status != SD_OK)
  47.     {
  48.         return(Status);
  49.     }

  50.     cardstatus = SDIO_GetResponse(SDIO_RESP1);

  51.     timeout = 10000;

  52.     while (((cardstatus & 0x00000100) == 0) && (timeout > 0))
  53.     {
  54.         /* CMD13 to polling the state of the card */
  55.         timeout--;
  56.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  57.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  58.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  59.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  60.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  61.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  62.         /* Check CMD errors */
  63.         Status = Check_Err_R1(SDIO_SEND_STATUS);
  64.         if (Status != SD_OK)
  65.         {
  66.             return(Status);
  67.         }

  68.         cardstatus = SDIO_GetResponse(SDIO_RESP1);
  69.     }

  70.     if (timeout == 0)
  71.     {
  72.         return(SD_ERROR);
  73.     }

  74.      /* CMD42 LOCK_UNLOCK */
  75.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)0x00000000;
  76.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_LOCK_UNLOCK;
  77.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  78.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  79.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  80.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  81.     /* Check CMD errors */
  82.     Status = Check_Err_R1(SDIO_LOCK_UNLOCK);
  83.     if (Status != SD_OK)
  84.     {
  85.         return(Status);
  86.     }

  87.     cardstatus = SDIO_GetResponse(SDIO_RESP1);

  88.     /* SDIO data transmisson config */
  89.     SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  90.     SDIO_DataInitStructure.SDIO_DataLength = 8;
  91.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_8B;
  92.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  93.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  94.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
  95.     SDIO_DataConfig(&SDIO_DataInitStructure);

  96.     /* Write PWD pattern */
  97.     SDIO_WriteData(pwd1);
  98.     SDIO_WriteData(pwd2);

  99.     if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
  100.     {
  101.         SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
  102.         Status = SD_DATA_TIMEOUT;
  103.         return(Status);
  104.     }
  105.     else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
  106.     {
  107.         SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
  108.         Status = SD_DATA_CRC_FAIL;
  109.         return(Status);
  110.     }
  111.     else if (SDIO_GetBitState(SDIO_FLAG_TXURE) != RESET)
  112.     {
  113.         SDIO_ClearBitState(SDIO_FLAG_TXURE);
  114.         Status = SD_TX_UNDERRUN;
  115.         return(Status);
  116.     }
  117.     else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
  118.     {
  119.         SDIO_ClearBitState(SDIO_FLAG_STBITE);
  120.         Status = SD_START_BIT_ERR;
  121.         return(Status);
  122.     }

  123.     /* Clear all the static flags */
  124.     SDIO_ClearBitState(SDIO_STATIC_FLAGS);

  125.     /* Wait till the card is in programming state */
  126.     Status = IsCardProgramming(&cardstate);
  127.     while ((Status == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  128.     {
  129.         Status = IsCardProgramming(&cardstate);
  130.     }

  131.     return(Status);
  132. }


renzheshengui 发表于 2020-4-7 14:13 | 显示全部楼层
非常感谢楼主分享
wakayi 发表于 2020-4-7 14:13 | 显示全部楼层
非常感谢楼主分享
wowu 发表于 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享
xiaoqizi 发表于 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享
磨砂 发表于 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部