当前位置: 首页 > news >正文

响应式网站 软件百度seo快速排名优化

响应式网站 软件,百度seo快速排名优化,页面设计心得体会,客源引流推广STM32F4X SDIO (九) 例程讲解-SD卡擦除、读写 例程讲解-SD卡擦除、读写SD卡擦除CMD32:ERASE_WR_BLK_START命令发送命令响应 CMD33:ERASE_WR_BLK_END命令发送命令响应CMD38:ERASE命令响应 CMD13:SD_CMD_SEND_STATUS命令发送命令回应 SD卡读数据CMD16:SET_…

STM32F4X SDIO (九) 例程讲解-SD卡擦除、读写

  • 例程讲解-SD卡擦除、读写
    • SD卡擦除
      • CMD32:ERASE_WR_BLK_START
        • 命令发送
        • 命令响应
      • CMD33:ERASE_WR_BLK_END
        • 命令发送
        • 命令响应
        • CMD38:ERASE
        • 命令响应
      • CMD13:SD_CMD_SEND_STATUS
        • 命令发送
        • 命令回应
    • SD卡读数据
      • CMD16:SET_BLOCKLEN
        • 命令发送
        • 命令响应
      • 设置SDIO控制传输数据类型
      • CMD18:READ_MULTIPLE_BLOCK
        • 命令发送
        • 命令响应
      • DMA配置
        • DMA接收配置
      • CMD12:STOP_TRANSMISSION
        • 命令发送
        • 命令响应
      • 等待SD卡读取完毕
        • 命令发送
        • 命令响应
      • 数据读取波形
    • SD卡写
      • CMD16:SET_BLOCKLEN
        • 命令发送
        • 命令响应
      • 设置SDIO控制传输数据类型
      • CMD24:WRITE_BLOCK
        • 命令发送
        • 命令响应
      • DMA配置
        • DMA发送配置
      • 等待SD卡写入完成
        • 命令发送
        • 命令响应
      • SD卡写数据波形

本节例程基于 野火电子的STM32F407的SD卡读写例程进行讲解。上一节中讲解了SD卡设置成4下模式的步骤,本节将会讲解SD卡的 擦除和读写操作

例程讲解-SD卡擦除、读写

SD卡擦除

针对SD卡这种存储设备,在写入数据之前都需要将数据进行擦除。对于SDHC容量的SD卡来说,最小的擦除单位扇区,一个扇区对应的大小是512字节

CMD32:ERASE_WR_BLK_START

在进行SD卡的擦除操作前,需要设置SD卡的擦除地址,擦除的地址有两个,分别是擦除的起始地址擦除的结束地址。对于标准SD卡来说,地址以字节为单位,对于标准SDHC来说,地址以块为单位。设置擦除起始地址的命令是CMD32
在这里插入图片描述

命令发送

CMD32命令需要的参数要擦除块的起始地址

 SDIO_CmdInitStructure.SDIO_Argument =(uint32_t)startaddr; // 起始地址SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_ERASE_GRP_START; // CMD32 SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机SDIO_SendCommand(&SDIO_CmdInitStructure);

这里面的起始地址设置为0,也就是擦除第一个扇区。
在这里插入图片描述

命令响应

CMD32的响应类型是R1,所以需要判断SD卡状态

static SD_Error CmdResp1Error(uint8_t cmd)
{SD_Error errorstatus = SD_OK;uint32_t status;uint32_t response_r1;status = SDIO->STA;while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))){status = SDIO->STA;}if (status & SDIO_FLAG_CTIMEOUT){errorstatus = SD_CMD_RSP_TIMEOUT;SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);return(errorstatus);}else if (status & SDIO_FLAG_CCRCFAIL){errorstatus = SD_CMD_CRC_FAIL;SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);return(errorstatus);}/*!< Check response received is of desired command */if (SDIO_GetCommandResponse() != cmd){errorstatus = SD_ILLEGAL_CMD;return(errorstatus);}/*!< Clear all the static flags */SDIO_ClearFlag(SDIO_STATIC_FLAGS);/*!< We have received response, retrieve it for analysis  */response_r1 = SDIO_GetResponse(SDIO_RESP1);if ((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO){return(errorstatus);}if (response_r1 & SD_OCR_ADDR_OUT_OF_RANGE){return(SD_ADDR_OUT_OF_RANGE);}if (response_r1 & SD_OCR_ADDR_MISALIGNED){return(SD_ADDR_MISALIGNED);}if (response_r1 & SD_OCR_BLOCK_LEN_ERR){return(SD_BLOCK_LEN_ERR);}if (response_r1 & SD_OCR_ERASE_SEQ_ERR){return(SD_ERASE_SEQ_ERR);}if (response_r1 & SD_OCR_BAD_ERASE_PARAM){return(SD_BAD_ERASE_PARAM);}if (response_r1 & SD_OCR_WRITE_PROT_VIOLATION){return(SD_WRITE_PROT_VIOLATION);}if (response_r1 & SD_OCR_LOCK_UNLOCK_FAILED){return(SD_LOCK_UNLOCK_FAILED);}if (response_r1 & SD_OCR_COM_CRC_FAILED){return(SD_COM_CRC_FAILED);}if (response_r1 & SD_OCR_ILLEGAL_CMD){return(SD_ILLEGAL_CMD);}if (response_r1 & SD_OCR_CARD_ECC_FAILED){return(SD_CARD_ECC_FAILED);}if (response_r1 & SD_OCR_CC_ERROR){return(SD_CC_ERROR);}if (response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR){return(SD_GENERAL_UNKNOWN_ERROR);}if (response_r1 & SD_OCR_STREAM_READ_UNDERRUN){return(SD_STREAM_READ_UNDERRUN);}if (response_r1 & SD_OCR_STREAM_WRITE_OVERRUN){return(SD_STREAM_WRITE_OVERRUN);}if (response_r1 & SD_OCR_CID_CSD_OVERWRIETE){return(SD_CID_CSD_OVERWRITE);}if (response_r1 & SD_OCR_WP_ERASE_SKIP){return(SD_WP_ERASE_SKIP);}if (response_r1 & SD_OCR_CARD_ECC_DISABLED){return(SD_CARD_ECC_DISABLED);}if (response_r1 & SD_OCR_ERASE_RESET){return(SD_ERASE_RESET);}if (response_r1 & SD_OCR_AKE_SEQ_ERROR){return(SD_AKE_SEQ_ERROR);}return(errorstatus);
}

在这里插入图片描述
CMD32返回的卡状态是0x900,根据SD卡状态表可知,当前SD卡已经转准备就绪,并且处于传输模式下。
在这里插入图片描述

CMD33:ERASE_WR_BLK_END

擦除操作中,除了需要设置擦除的起始地址外,还需要设置擦除的结束地址
在这里插入图片描述

命令发送

CMD33命令需要的参数要擦除块的结束地址

 SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)endaddr;// 起始地址 SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_ERASE_GRP_END;// CMD33SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;// 短响应SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述
从波形图可以可以看到,程序中设置的擦除结束地址是51200,也就是擦除100个扇区。

命令响应

CMD33的响应类型是R1,所以需要判断SD卡状态

static SD_Error CmdResp1Error(uint8_t cmd)
{SD_Error errorstatus = SD_OK;uint32_t status;uint32_t response_r1;status = SDIO->STA;while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))){status = SDIO->STA;}if (status & SDIO_FLAG_CTIMEOUT){errorstatus = SD_CMD_RSP_TIMEOUT;SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);return(errorstatus);}else if (status & SDIO_FLAG_CCRCFAIL){errorstatus = SD_CMD_CRC_FAIL;SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);return(errorstatus);}/*!< Check response received is of desired command */if (SDIO_GetCommandResponse() != cmd){errorstatus = SD_ILLEGAL_CMD;return(errorstatus);}/*!< Clear all the static flags */SDIO_ClearFlag(SDIO_STATIC_FLAGS);/*!< We have received response, retrieve it for analysis  */response_r1 = SDIO_GetResponse(SDIO_RESP1);if ((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO){return(errorstatus);}if (response_r1 & SD_OCR_ADDR_OUT_OF_RANGE){return(SD_ADDR_OUT_OF_RANGE);}if (response_r1 & SD_OCR_ADDR_MISALIGNED){return(SD_ADDR_MISALIGNED);}if (response_r1 & SD_OCR_BLOCK_LEN_ERR){return(SD_BLOCK_LEN_ERR);}if (response_r1 & SD_OCR_ERASE_SEQ_ERR){return(SD_ERASE_SEQ_ERR);}if (response_r1 & SD_OCR_BAD_ERASE_PARAM){return(SD_BAD_ERASE_PARAM);}if (response_r1 & SD_OCR_WRITE_PROT_VIOLATION){return(SD_WRITE_PROT_VIOLATION);}if (response_r1 & SD_OCR_LOCK_UNLOCK_FAILED){return(SD_LOCK_UNLOCK_FAILED);}if (response_r1 & SD_OCR_COM_CRC_FAILED){return(SD_COM_CRC_FAILED);}if (response_r1 & SD_OCR_ILLEGAL_CMD){return(SD_ILLEGAL_CMD);}if (response_r1 & SD_OCR_CARD_ECC_FAILED){return(SD_CARD_ECC_FAILED);}if (response_r1 & SD_OCR_CC_ERROR){return(SD_CC_ERROR);}if (response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR){return(SD_GENERAL_UNKNOWN_ERROR);}if (response_r1 & SD_OCR_STREAM_READ_UNDERRUN){return(SD_STREAM_READ_UNDERRUN);}if (response_r1 & SD_OCR_STREAM_WRITE_OVERRUN){return(SD_STREAM_WRITE_OVERRUN);}if (response_r1 & SD_OCR_CID_CSD_OVERWRIETE){return(SD_CID_CSD_OVERWRITE);}if (response_r1 & SD_OCR_WP_ERASE_SKIP){return(SD_WP_ERASE_SKIP);}if (response_r1 & SD_OCR_CARD_ECC_DISABLED){return(SD_CARD_ECC_DISABLED);}if (response_r1 & SD_OCR_ERASE_RESET){return(SD_ERASE_RESET);}if (response_r1 & SD_OCR_AKE_SEQ_ERROR){return(SD_AKE_SEQ_ERROR);}return(errorstatus);
}

在这里插入图片描述
CMD33返回的卡状态是0x900,根据SD卡状态表可知,当前SD卡已经转准备就绪,并且处于传输模式下。
在这里插入图片描述

CMD38:ERASE

设置好需要擦除的起始地址和结束地址后,就可以调用CMD38命令擦除扇区。
在这里插入图片描述

 SDIO_CmdInitStructure.SDIO_Argument = 0; // 参数为0SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_ERASE; // CMD38SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;// 不等待SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;// 使能CPSM状态机SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD38的响应类型是R1b,所以需要判断SD卡状态

static SD_Error CmdResp1Error(uint8_t cmd)
{SD_Error errorstatus = SD_OK;uint32_t status;uint32_t response_r1;status = SDIO->STA;while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))){status = SDIO->STA;}if (status & SDIO_FLAG_CTIMEOUT){errorstatus = SD_CMD_RSP_TIMEOUT;SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);return(errorstatus);}else if (status & SDIO_FLAG_CCRCFAIL){errorstatus = SD_CMD_CRC_FAIL;SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);return(errorstatus);}/*!< Check response received is of desired command */if (SDIO_GetCommandResponse() != cmd){errorstatus = SD_ILLEGAL_CMD;return(errorstatus);}/*!< Clear all the static flags */SDIO_ClearFlag(SDIO_STATIC_FLAGS);/*!< We have received response, retrieve it for analysis  */response_r1 = SDIO_GetResponse(SDIO_RESP1);if ((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO){return(errorstatus);}if (response_r1 & SD_OCR_ADDR_OUT_OF_RANGE){return(SD_ADDR_OUT_OF_RANGE);}if (response_r1 & SD_OCR_ADDR_MISALIGNED){return(SD_ADDR_MISALIGNED);}if (response_r1 & SD_OCR_BLOCK_LEN_ERR){return(SD_BLOCK_LEN_ERR);}if (response_r1 & SD_OCR_ERASE_SEQ_ERR){return(SD_ERASE_SEQ_ERR);}if (response_r1 & SD_OCR_BAD_ERASE_PARAM){return(SD_BAD_ERASE_PARAM);}if (response_r1 & SD_OCR_WRITE_PROT_VIOLATION){return(SD_WRITE_PROT_VIOLATION);}if (response_r1 & SD_OCR_LOCK_UNLOCK_FAILED){return(SD_LOCK_UNLOCK_FAILED);}if (response_r1 & SD_OCR_COM_CRC_FAILED){return(SD_COM_CRC_FAILED);}if (response_r1 & SD_OCR_ILLEGAL_CMD){return(SD_ILLEGAL_CMD);}if (response_r1 & SD_OCR_CARD_ECC_FAILED){return(SD_CARD_ECC_FAILED);}if (response_r1 & SD_OCR_CC_ERROR){return(SD_CC_ERROR);}if (response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR){return(SD_GENERAL_UNKNOWN_ERROR);}if (response_r1 & SD_OCR_STREAM_READ_UNDERRUN){return(SD_STREAM_READ_UNDERRUN);}if (response_r1 & SD_OCR_STREAM_WRITE_OVERRUN){return(SD_STREAM_WRITE_OVERRUN);}if (response_r1 & SD_OCR_CID_CSD_OVERWRIETE){return(SD_CID_CSD_OVERWRITE);}if (response_r1 & SD_OCR_WP_ERASE_SKIP){return(SD_WP_ERASE_SKIP);}if (response_r1 & SD_OCR_CARD_ECC_DISABLED){return(SD_CARD_ECC_DISABLED);}if (response_r1 & SD_OCR_ERASE_RESET){return(SD_ERASE_RESET);}if (response_r1 & SD_OCR_AKE_SEQ_ERROR){return(SD_AKE_SEQ_ERROR);}return(errorstatus);
}

在这里插入图片描述

CMD38返回的卡状态是0x800,根据SD卡状态表可知,当前SD卡处于"not ready"状态。也就是还在擦除扇区中
在这里插入图片描述

CMD13:SD_CMD_SEND_STATUS

CMD13的作用是查询SD的状态,判断SD卡是否擦除完成。
在这里插入图片描述

命令发送

CMD13命令发送是需要带参数,参数是需要查询的SD卡的RCA地址

 SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;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);

在这里插入图片描述

命令回应

在这里插入图片描述
由波形图可知,CMD13返回的SD卡状态是0x900,也就是当前SD卡已经擦除完成,准备就绪。

SD卡读数据

CMD16:SET_BLOCKLEN

在开始读数据之前,需要设置需要读取的数据块大小,对于SDHC容量的SD卡来说,数据块大小为512字节
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize; // 数据块大小 SDHC为512字节
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN; // 命令索引 CMD16
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;// 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD16的命令响应是R1,需要判断SD卡状态

在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

设置SDIO控制传输数据类型

设置完SD卡块大小之后,还需要设置SDIO控制器的数据传输类型,在例程中我们需要读取100个扇区的数据,也就是需要读取512 * 100总共51200字节的数据。

SDIO_DataInitStruct.SDIO_DataTimeOut = SD_DATATIMEOUT; // 传输超时时间
SDIO_DataInitStruct.SDIO_DataLength = NumberOfBlocks * BlockSize; // 传输数据大小 512 * 100
SDIO_DataInitStruct.SDIO_DataBlockSize = (uint32_t) 9 << 4; // 数据块大小 512字节
SDIO_DataInitStruct.SDIO_TransferDir = SDIO_TransferDir_ToSDIO; //传输方向 从SD卡到SDIO控制器
SDIO_DataInitStruct.SDIO_TransferMode = SDIO_TransferMode_Block; // 传输类型 块传输
SDIO_DataInitStruct.SDIO_DPSM = SDIO_DPSM_Enable; // 使能DPSM状态机
SDIO_DataConfig(&SDIO_DataInitStruct);

CMD18:READ_MULTIPLE_BLOCK

CMD18作用是读取多个扇区数据,CMD18需要传入一个数据的起始地址
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr; // 数据读取的起始地址
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_MULT_BLOCK; // 命令索引 CMD18
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD18的命令响应是R1,需要判断SD卡状态
在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

DMA配置

一般情况下,在进行SD卡数据传输时,因为传输的数据量都比较大,所以一般都会使用DMA进行传输。

DMA接收配置

以下是例程中的接收DMA配置。

void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize)
{DMA_InitTypeDef SDDMA_InitStructure;DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);/* DMA2 Stream3  or Stream6 disable */DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);/* DMA2 Stream3 or Stream6 Config */DMA_DeInit(SD_SDIO_DMA_STREAM);SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferDST;SDDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;SDDMA_InitStructure.DMA_BufferSize = 1;SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);/* DMA2 Stream3 or Stream6 enable */DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
}

CMD12:STOP_TRANSMISSION

在进行SD卡的多数据块传输时,当所有数据块都读取完成后,我们需要发送CMD12命令,告诉SD卡停止传输
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = 0; 
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION; // 命令索引 CMD12
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD12的命令响应是R1b,需要判断SD卡状态
在这里插入图片描述

等待SD卡读取完毕

当我们向SD卡发送完CMD12命令后,需要发送CMD13不断读取SD卡状态,判断SD卡是否读取完成
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS; // 命令索引 CMD13
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

数据读取波形

在这里插入图片描述

SD卡写

SD卡的写过程跟SD卡的读过程差不多。只不过数据传输方向相反

CMD16:SET_BLOCKLEN

在开始写数据之前,需要设置需要读取的数据块大小,对于SDHC容量的SD卡来说,数据块大小为512字节
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize; // 数据块大小 SDHC为512字节
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN; // 命令索引 CMD16
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;// 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD16的命令响应是R1,需要判断SD卡状态

在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

设置SDIO控制传输数据类型

设置完SD卡块大小之后,还需要设置SDIO控制器的数据传输类型,在例程中我们需要读取1个扇区的数据,也就是需要读取512总共51200字节的数据。

SDIO_DataInitStruct.SDIO_DataTimeOut = SD_DATATIMEOUT; // 传输超时时间
SDIO_DataInitStruct.SDIO_DataLength = BlockSize; // 传输数据大小 512字节
SDIO_DataInitStruct.SDIO_DataBlockSize = (uint32_t) 9 << 4; // 数据块大小 512字节
SDIO_DataInitStruct.SDIO_TransferDir = SDIO_TransferDir_ToCard; //传输方向 从SDIO控制器到SD卡
SDIO_DataInitStruct.SDIO_TransferMode = SDIO_TransferMode_Block; // 传输类型 块传输
SDIO_DataInitStruct.SDIO_DPSM = SDIO_DPSM_Enable; // 使能DPSM状态机
SDIO_DataConfig(&SDIO_DataInitStruct);

CMD24:WRITE_BLOCK

CMD24的作用是写单个块。CMD24需要带参数,参数是写入的扇区地址
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)WriteAddr; // 扇区地址 0地址
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN; // 命令索引 CMD24
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;// 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

CMD24的命令响应是R1,需要判断SD卡状态
在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

DMA配置

DMA发送配置

以下是例程中的DMA发送配置。

void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)
{DMA_InitTypeDef SDDMA_InitStructure;DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);/* DMA2 Stream3  or Stream6 disable */DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);/* DMA2 Stream3  or Stream6 Config */DMA_DeInit(SD_SDIO_DMA_STREAM);SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferSRC;SDDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;SDDMA_InitStructure.DMA_BufferSize = 1;SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);/* DMA2 Stream3  or Stream6 enable */DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);}

等待SD卡写入完成

由于例程中是只写一个扇区,所以不用发送CMD12强制停止传输,但是我们需要发送CMD13不断读取SD卡状态,判断SD卡是否读取完成
在这里插入图片描述

命令发送
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS; // 命令索引 CMD13
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; // 短响应
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; // 不等待
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; // 使能CPSM状态机
SDIO_SendCommand(&SDIO_CmdInitStructure);

在这里插入图片描述

命令响应

在这里插入图片描述
从波形图可知,SD卡总线已经准备就绪,并且进入tran状态。
在这里插入图片描述

SD卡写数据波形

在这里插入图片描述

http://www.yayakq.cn/news/881254/

相关文章:

  • 网站制作好了怎么上传网页制作基础教程步骤
  • 长沙网站制作作西安建设工程交易中心官网
  • 乔拓云建站平台不是免费的长沙专业做网站
  • 最牛论坛网站wordpress 页面nofollow
  • 电子商务网站的开发流程包括高端网站建设苏州
  • 020网站建设和维护费用WordPress怎么添加音乐
  • 4大门户网站物流网站建设流程图
  • 青岛做网站方案莱芜市在线论坛话题
  • 信息网站开发国外门户网站设计
  • 行业网站建设内容开封网站建设培训
  • 网站开发PHP留言本电子版实验作品新加坡网络公司排名
  • 网站设计制作平台哪个好百度关键词优化平台
  • 无锡手机网站建设介绍常见的网络营销方式
  • 网站平台搭建国内做贵金属返佣比较多的网站
  • 上海建筑建材业网站迁移js检测网站是否能打开
  • 机械网站建设公司网页制作网站源码
  • 建一个网站需要哪些知识旅游网站怎样做宣传
  • 想做水果外卖怎么做网站简述sem对seo的影响
  • 怎么做加盟美容院网站为什么我有的网站打不开
  • 晋江做任务的网站wordpress建站更换图片
  • wordpress调用文章方法广州网站优化方式
  • wordpress 站群会员江西网络推广
  • 红色大气网络公司企业网站源码_适合广告设计网站建设项目的工作分解
  • 网乐科技网站建设vue做电商网站
  • 凡科建设网站步骤网站内容被攻击该怎么做
  • 吉林北京网站建设大型社区网站开发文档
  • 江西数据平台网站建设低调与华丽wordpress
  • 誉重网站建设脚上起小水泡很痒是什么原因
  • 自己做盗号网站wordpress用什么服务
  • 如何建立企业网站或者官网网站备案 收费