W806使用SDIO方式初始化SD卡時,發送CMD2命令後獲取響應R2失敗,希望大神指點。
發送CMD2獲取CID的R2響應時失敗,SD卡2.0手冊R2響應Bit[135-128]=0x3F,程序讀取該值一直為0
程序如下:{{sdio.c(uploading...)}}
uint8 SD_CardType=0;
// SD卡類型定義
//SD卡指令表
//MMC_IO配置
enum SdCardResponse {SDIOCmdError,SDIOCmdTrue};//命令響應判斷
enum SDflag { SDTrue,SDFall}; //函數返回值:成功/失敗
void Init_SDIO_IO()
{
RCC->RST&=~BIT(SDIO_CLK_RE);
RCC->RST|=BIT(SDIO_CLK_RE);
while(!(RCC->RST&BIT(SDIO_CLK_RE))); //複位SDIO模塊
RCC->CLK_EN|=BIT(SDIO_CLK_EN);
RCC->CLK_MASK|=BIT(1); //時鐘使能
SDIO_GPIO->DATA_B_EN|=BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3);
SDIO_GPIO->PULLUP_EN&=~(BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3));
SDIO_GPIO->DIR|=BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3);
SDIO_GPIO->DATA|=BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3);
SDIO_GPIO->AF_SEL|=BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3);
SDIO_GPIO->AF_S0|=BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3);
SDIO_GPIO->AF_S1&=~(BIT(SDIO_CLK)|BIT(SDIO_CMD)|BIT(SDIO_D0)|BIT(SDIO_D1)|BIT(SDIO_D2)|BIT(SDIO_D3));
}
void SDIO_LowSpeed()
{
SDIO->MMC_CTL&=0x7C7;
SDIO->MMC_CTL|=BIT(5)|BIT(3);
SDIO->MMC_CARDSEL&=0xC0;
SDIO->MMC_CARDSEL|=0x18;
SDIO->MMC_CTL&=~BIT(6);
}
void WaiteCmdTransOver()
{
while(!(SDIO->MMC_INT_SRC&BIT(0)));//等待命令傳輸完成
SDIO->MMC_INT_SRC|=BIT(0); //清零標志位
}
void SD_SendCmd(uint8 cmd,uint32 cmdarg,uint8 mmcio)
{
SDIO->CMD_BUFF[4]=(cmd|0x40);
SDIO->CMD_BUFF[3]=((cmdarg>>24)&0xFF);
SDIO->CMD_BUFF[2]=((cmdarg>>16)&0xFF);
SDIO->CMD_BUFF[1]=((cmdarg>>8)&0xFF);
SDIO->CMD_BUFF[0]=(cmdarg&0xFF);
SDIO->MMC_INT_SRC|=0x1FF;
SDIO->MMC_IO=mmcio;
if(cmd==CMD12)
{
//
}
}
void Init_SDIO_Reg()
{
SDIO->MMC_CARDSEL|=BIT(7)|BIT(6);
SDIO->MMC_CTL=BIT(1)|BIT(0);//1bit模式
SDIO->MMC_PORT=0xFF;
SDIO->MMC_CRCCTL=BIT(7)|BIT(6);
}
uint8 SDIO_GetResponseR1(uint8 cmd,uint32 指針符號 responR1)
{
while(!(SDIO->MMC_INT_SRC&BIT(6)))
{
if(SDIO->MMC_INT_SRC&BIT(0))
{
SDIO->MMC_INT_SRC|=BIT(0);
if((SDIO->CMD_BUFF[4]&0x3F)==cmd)
{
指針符號 responR1=((SDIO->CMD_BUFF[3]<<24)+(SDIO->CMD_BUFF[2]<<16)+(SDIO->CMD_BUFF[1]<<8)+(SDIO->CMD_BUFF[0]));
return SDIOCmdTrue;
}
}
}
SDIO->MMC_INT_SRC|=BIT(6);
return SDIOCmdError;
}
uint8 SDIO_GetResponseR2(uint8 指針符號 responR2buff)
{
uint8 i=0;
for(i=0;i<200;i++)
{
while(!(SDIO->MMC_INT_SRC&BIT(0)));
SDIO->MMC_INT_SRC|=BIT(0);
printf("ResponR2[135-128]=%d\n",SDIO->CMD_BUFF[15]);//R2響應失敗
if(SDIO->CMD_BUFF[15]==0x3F)
{
printf("ResponR2[135-128]=%d\n",SDIO->CMD_BUFF[15]);
for(i=0;i<15;i++)
{
指針符號 responR2buff++=SDIO->CMD_BUFF[i];
printf("CID[%d]=%d\n",i,SDIO->CMD_BUFF[i]);
}
return SDIOCmdTrue;
}else
{
SD_SendCmd(CMD2,0,MMC_IO_RradCidCsdRecp);
}
}
return SDIOCmdError;
}
uint8 SDIO_GetResponseR3(uint32 指針符號 responR3)
{
while(!(SDIO->MMC_INT_SRC&BIT(6)))
{
if(SDIO->MMC_INT_SRC&BIT(0))
{
SDIO->MMC_INT_SRC|=BIT(0);
指針符號 responR3=((SDIO->CMD_BUFF[3]<<24)+(SDIO->CMD_BUFF[2]<<16)+(SDIO->CMD_BUFF[1]<<8)+(SDIO->CMD_BUFF[0]));
return SDIOCmdTrue;
}
}
SDIO->MMC_INT_SRC|=BIT(6);
return SDIOCmdError;
}
uint8 Init_SDCard()
{
uint8 respon,cnt=0;
uint32 ReState;
uint16 SD_RCA,SD_State;
uint8 cid_csd_buff[16]; //獲取CID、CSD緩存
Init_SDIO_IO();
Init_SDIO_Reg();
SDIO_LowSpeed();
for(cnt=0;cnt<10;cnt++)// 74個CLK
{
SDIO->MMC_IO=MMC_IO_JusCret8nck;
while(SDIO->MMC_IO&BIT(2));
}
SD_SendCmd(CMD0,0,MMC_IO_SendCmd6);//複位卡
WaiteCmdTransOver();
可以看看這篇文章,可能對你有幫助。http://ask.winnermicro.com/article/36.html