能上传个使用的例程(Project)就好了。。。 SD_Error CmdResp3Error(void)
{
u32 status;
while(1)
{
status = SDIO1->STS;
if(status & ((1 << 0) | (1 << 2) | (1 << 6))) //CRC错误/命令响应超时/已经收到响应
{
break;
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDTIMEOUT) != RESET) //响应超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return SD_CMD_RSP_TIMEOUT;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS);
return SD_OK;
} SD_Error CmdResp2Error(void)
{
SD_Error errorstatus = SD_OK;
u32 status;
u32 timeout = SDIO_CMD0TIMEOUT;
while(timeout--)
{
status = SDIO1->STS;
if(status & ((1 << 0) | (1 << 2) | (1 << 6))) //CRC错误/命令响应超时/已经收到响应
{
break;
}
}
if((timeout == 0) || (status & (1 << 2))) //响应超时
{
errorstatus = SD_CMD_RSP_TIMEOUT;
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return errorstatus;
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDFAIL) != RESET) //CRC错误
{
errorstatus = SD_CMD_FAIL;
SDIO_ClearFlag(SDIO1, SDIO_**_CMDFAIL);
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS); //清除所有标记
return errorstatus;
} SD_Error CmdResp4Error(u8 cmd)
{
u32 status;
while(1)
{
status = SDIO1->STS;
if(status & ((1 << 0) | (1 << 2) | (1 << 6))) //CRC错误/命令响应超时/已经收到响应
{
break;
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDTIMEOUT) != RESET) //响应超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return SD_CMD_RSP_TIMEOUT;
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDFAIL) != RESET) //CRC错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDFAIL);
return SD_CMD_FAIL;
}
if(SDIO1->RSPCMD != cmd) //命令不匹配
{
return SD_ILLEGAL_CMD;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS); //清除所有标记
return SD_OK;
} SD_Error CmdResp5Error(u8 cmd)
{
u32 status;
while(1)
{
status = SDIO1->STS;
if(status & ((1 << 0) | (1 << 2) | (1 << 6))) //CRC错误/命令响应超时/已经收到响应
{
break;
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDTIMEOUT) != RESET) //响应超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return SD_CMD_RSP_TIMEOUT;
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDFAIL) != RESET) //CRC错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDFAIL);
return SD_CMD_FAIL;
}
if(SDIO1->RSPCMD != cmd) //命令不匹配
{
return SD_ILLEGAL_CMD;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS);
if (SDIO1->RSP1 & SD_R5_OUT_OF_RANGE)
{
return SD_CMD_OUT_OF_RANGE;
}
if (SDIO1->RSP1 & SD_R5_FUNCTION_NUMBER)
{
return SD_SDIO_UNKNOWN_FUNC;
}
if (SDIO1->RSP1 & SD_R5_ERROR)
{
return SD_GENERAL_UNKNOWN_ERROR;
}
return SD_OK;
} SD_Error CmdResp6Error(u8 cmd, u16*prca)
{
SD_Error errorstatus = SD_OK;
u32 status;
u32 rspr1;
while(1)
{
status = SDIO1->STS;
if(status & ((1 << 0) | (1 << 2) | (1 << 6))) //CRC错误/命令响应超时/已经收到响应
{
break;
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDTIMEOUT) != RESET) //响应超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return SD_CMD_RSP_TIMEOUT;
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDFAIL) != RESET) //CRC错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDFAIL);
return SD_CMD_FAIL;
}
if(SDIO1->RSPCMD != cmd) //判断是否响应cmd命令
{
return SD_ILLEGAL_CMD;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS); //清除所有标记
rspr1 = SDIO1->RSP1;
if(SD_ALLZERO == (rspr1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_CMD_CRC_FAILED)))
{
*prca = (u16)(rspr1 >> 16);
return errorstatus;
}
if(rspr1 & SD_R6_GENERAL_UNKNOWN_ERROR)
{
return SD_GENERAL_UNKNOWN_ERROR;
}
if(rspr1 & SD_R6_ILLEGAL_CMD)
{
return SD_ILLEGAL_CMD;
}
if(rspr1 & SD_R6_CMD_CRC_FAILED)
{
return SD_CMD_CRC_FAILED;
}
return errorstatus;
}
SD_Error SDEnWideBus(u8 enx)
{
SD_Error errorstatus = SD_OK;
u8 arg = 0X00;
if(enx)
{
arg = 0X02;
}
else
{
arg = 0X00;
}
if(SDIO1->RSP1 & SD_CARD_LOCKED) //SD卡处于LOCKED状态
{
return SD_LOCK_UNLOCK_FAILED;
}
if(SDCardInfo.SD_scr.SD_BUS_WIDTHS) //支持宽总线
{
SDIO_CmdInitStructure.SDIO_Argu = (uint32_t) SDCardInfo.RCA << 16;//发送CMD55+RCA,短响应
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_APP_CMD;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_APP_CMD);
if(errorstatus != SD_OK)
{
return errorstatus;
}
SDIO_CmdInitStructure.SDIO_Argu = arg; //发送ACMD6,短响应,参数:10,4位;00,1位.
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_APP_SD_SET_BUSWIDTH;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);
return errorstatus;
}
else
{
return SD_REQ_NOT_APPLICABLE;//不支持宽总线设置
}
} SD_Error MMC_Switch(u8 set, u8 index, u8 value)
{
SD_Error errorstatus = SD_OK;
u32 cardstatus = 0;
u32 timeout = 0;
SDIO_CmdInitStructure.SDIO_Argu = (EXT_CSD_Write_byte << 24) | (index << 16) | (value << 8) | set;
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_HS_SWITCH;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_HS_SWITCH); //等待R1响应
if(errorstatus != SD_OK)
{
;
}
cardstatus = SDIO1->RSP1;
if(cardstatus & MMC_SWITCH_ERROR)
{
return SD_SWITCH_ERROR;
}
timeout = SD_DATATIMEOUT;
do
{
timeout--;
errorstatus = SD_SendStatus(&cardstatus);
}
while(((cardstatus & 0x00000100) == 0) && (timeout > 0)); //检查READY_FOR_DATA位是否置位
if(timeout == 0)
{
return SD_ERROR;
}
return errorstatus;
} SD_Error SD_Switch(u32 mode, u32 group, u8 value, u8 *resp)
{
SD_Error errorstatus = SD_OK;
u8 power;
u16 blksize;
if(NULL == resp)
{
return SD_INVALID_PARAMETER;
}
SDIO1->DTCTRL = 0x0; //数据控制寄存器清零(关DMA)
blksize = 64;
power = convert_from_bytes_to_power_of_two(blksize);
SDIO_CmdInitStructure.SDIO_Argu =blksize;
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_SET_BLOCKLEN;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure); //发送CMD16+设置数据长度为blksize,短响应
errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
if(errorstatus != SD_OK)
{
return errorstatus;//响应错误
}
SDIO_DataInitStructure.SDIO_DataBlkSize = power << 4 ; //清除DPSM状态机配置
SDIO_DataInitStructure.SDIO_DataLen = blksize ;
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT ;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_CmdInitStructure.SDIO_Argu = mode << 31 | 0x00FFFFFF;
SDIO_CmdInitStructure.SDIO_Argu &= ~(0xF << (group * 4));
SDIO_CmdInitStructure.SDIO_Argu |= value << (group * 4);
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_HS_SWITCH;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
StopCondition = 0;
return SDIO_SendDataCommand(&SDIO_CmdInitStructure, &SDIO_DataInitStructure, (u32 *)resp);
}
SD_Error IsCardProgramming(u8 *pstatus)
{
vu32 respR1 = 0, status = 0;
SDIO_CmdInitStructure.SDIO_Argu = (uint32_t) RCA << 16; //卡相对地址参数
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_SEND_STATUS;//发送CMD13
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
status = SDIO1->STS;
while(!(status & ((1 << 0) | (1 << 6) | (1 << 2))))
{
status = SDIO1->STS;//等待操作完成
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDFAIL) != RESET) //CRC检测失败
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDFAIL);
return SD_CMD_FAIL;
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_CMDTIMEOUT) != RESET) //命令超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_CMDTIMEOUT);
return SD_CMD_RSP_TIMEOUT;
}
if(SDIO1->RSPCMD != SD_CMD_SEND_STATUS)
{
return SD_ILLEGAL_CMD;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS);
respR1 = SDIO1->RSP1;
*pstatus = (u8)((respR1 >> 9) & 0x0000000F);
return SD_OK;
} SD_Error SD_SendStatus(u32 *pcardstatus)
{
SD_Error errorstatus = SD_OK;
if(pcardstatus == NULL)
{
errorstatus = SD_INVALID_PARAMETER;
return errorstatus;
}
SDIO_CmdInitStructure.SDIO_Argu = (uint32_t) RCA << 16;//发送CMD13,短响应
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_SEND_STATUS;
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_SEND_STATUS);//查询响应状态
if(errorstatus != SD_OK)
{
return errorstatus;
}
*pcardstatus = SDIO1->RSP1; //读取响应值
return errorstatus;
}
SDCardState SD_GetState(void)
{
u32 resp1 = 0;
if(SD_SendStatus(&resp1) != SD_OK)
{
return SD_CARD_ERROR;
}
else
{
return (SDCardState)((resp1 >> 9) & 0x0F);
}
}
SD_Error FindSCR(void)
{
u32 index = 0;
SD_Error errorstatus = SD_OK;
u32 *tempscr;
tempscr = (u32 *) & (SDCardInfo.SD_scr);
SDIO_CmdInitStructure.SDIO_Argu = (uint32_t)8; //发送CMD16
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_SET_BLOCKLEN; //cmd16
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;//r1
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);
if(errorstatus != SD_OK)
{
return errorstatus;
}
SDIO_CmdInitStructure.SDIO_Argu = (uint32_t) SDCardInfo.RCA << 16;
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_APP_CMD;//发送CMD55
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_APP_CMD);
if(errorstatus != SD_OK)
{
return errorstatus;
}
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLen = 8;
SDIO_DataInitStructure.SDIO_DataBlkSize = SDIO_DataBlkSize_8b;//块大小8byte
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataConfig(SDIO1, &SDIO_DataInitStructure);
SDIO_CmdInitStructure.SDIO_Argu = 0x0;
SDIO_CmdInitStructure.SDIO_CmdIdx = SD_CMD_SD_APP_SEND_SCR; //发送ACMD51
SDIO_CmdInitStructure.SDIO_Resp = SDIO_Rsp_Short;//r1
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, &SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_SD_APP_SEND_SCR);
if(errorstatus != SD_OK)
{
return errorstatus;
}
while(!(SDIO1->STS & (SDIO_**_RXERRO | SDIO_**_DTFAIL | SDIO_**_DTTIMEOUT | SDIO_**_DTBLKCMPL | SDIO_**_SBITERR)))
{
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_RXBUF) != RESET) //接收FIFO数据可用
{
*(tempscr + index) = SDIO_ReadData(SDIO1); //读取FIFO内容
index++;
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_DTTIMEOUT) != RESET) //数据超时错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_DTTIMEOUT);
return SD_DATA_TIMEOUT;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_DTFAIL) != RESET) //数据块CRC错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_DTFAIL);
return SD_DATA_FAIL;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_RXERRO) != RESET) //接收fifo上溢错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_RXERRO);
return SD_RX_OVERRUN;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_SBITERR) != RESET)//接收起始位错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_SBITERR);
return SD_START_BIT_ERR;
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS); //清除所有标记
return errorstatus;
} SD_Error ChangeSpeed(u8 speed)
{
SD_Error errorstatus = SD_OK;
u8 SwitchSts;
if (speed > 1)
{
return SD_ERROR;
}
if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) //判断卡类型
{
/* Version 1.01 Card does not support CMD6 */
if (SDCardInfo.SD_scr.SD_SPEC == 0)
{
return SD_ERROR;
}
/* Check Group 1 function support speed*/
errorstatus = SD_Switch(0, 0, speed, SwitchSts);
if (errorstatus != 0)
{
return errorstatus;
}
if ((SwitchSts & (1 << speed)) == 0)
{
return SD_ERROR;
}
errorstatus = SD_Switch(1, 0, speed, SwitchSts);
if (errorstatus != 0)
{
return errorstatus;
}
/* Read it back for confirmation */
if ((SwitchSts & 0xF) != speed)
{
return SD_ERROR;
}
}
else if(SDIO_HIGH_SPEED_MULTIMEDIA_CARD == CardType)
{
errorstatus = MMC_Switch(EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, (u8)speed);
if (errorstatus != 0)
{
return errorstatus;
}
}
return errorstatus;
} u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes)
{
u8 count = 0;
while(NumberOfBytes != 1)
{
NumberOfBytes >>= 1;
count++;
}
return count;
} void SD_DMA_Config(u32*mbuf, u32 bufsize, u32 DMA_DIR)
{
DMA_InitType DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA2, ENABLE); //使能DMA2时钟
DMA_Reset(DMA2_Channel4); //复位DMA2通道4
DMA_ChannelEnable(DMA2_Channel4, DISABLE); //关闭DMA2通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO1->BUF;//DMA外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)mbuf;//DMA内存基地址
DMA_InitStructure.DMA_Direction = DMA_DIR;//数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = bufsize / 4; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;//外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;//内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_WORD;//数据宽度为32位
DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_WORD; //数据宽度为32位
DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;//工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;//DMA通道x没有设置为内存到内存传输
DMA_Init(DMA2_Channel4, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
DMA_ChannelEnable(DMA2_Channel4, ENABLE); //开启DMA2 通道4
}
页:
1
[2]