W806开发板SDIO方式初始化SD卡时发送CMD2读取CID时R2响应失败

发布于 2022-11-01 16:33:50

W806使用SDIO方式初始化SD卡时,发送CMD2命令后获取响应R2失败,希望大神指点。
1.PNG
2.PNG
发送CMD2获取CID的R2响应时失败,SD卡2.0手册R2响应Bit[135-128]=0x3F,程序读取该值一直为0
程序如下:{{sdio.c(uploading...)}}

3.jpg

define SDIO SDIO_HOST

define CMD_BUFF[x] CMD_BUF[x]

define SDIO_CLK PB6

define SDIO_CMD PB7

define SDIO_D0 PB8

define SDIO_D1 PB9

define SDIO_D2 PB10

define SDIO_D3 PB11//OPT2

define SDIO_GPIO GPIOB

uint8 SD_CardType=0;
// SD卡类型定义

define SD_TYPE_ERR 0x00

define SD_TYPE_MMC 0x01

define SD_TYPE_V1 0x02

define SD_TYPE_V2 0x04

define SD_TYPE_V2HC 0x06

//SD卡指令表

define CMD0 0 //卡复位

define CMD1 1

define CMD2 2

define CMD3 3

define CMD8 8 //命令8 ,SEND_IF_COND

define CMD9 9 //命令9 ,读CSD数据

define CMD10 10 //命令10,读CID数据

define CMD12 12 //命令12,停止数据传输

define CMD16 16 //命令16,设置SectorSize 应返回0x00

define CMD17 17 //命令17,读sector

define CMD18 18 //命令18,读Multi sector

define CMD23 23 //命令23,设置多sector写入前预先擦除N个block

define CMD24 24 //命令24,写sector

define CMD25 25 //命令25,写Multi sector

define CMD41 41 //命令41,应返回0x00

define CMD55 55 //命令55,应返回0x01

define CMD58 58 //命令58,读OCR信息

define CMD59 59 //命令59,使能/禁止CRC,应返回0x00

define MMC_CMD1_ARG 0x80FF8000 //MMC卡CMD1命令参数

//MMC_IO配置

define MMC_IO_NoAction 0 //MMC_IO无操作

define MMC_IO_JusCret8nck 0x24 //MMC_IO生成8个空闲时钟

define MMC_IO_SendCmd6 0x04 //发送6字节命令

define MMC_IO_Response6 0x0C //接收6字节响应

define MMC_IO_Response17 0x1C //接收17字节响应

define MMC_IO_Cmd8nclk 0x84 //传输命令+8个空闲时钟

define MMC_IO_CmdRecSp 0x44 //传输命令+接收响应

define MMC_IO_RradCidCsdRecp 0x54 //传输命令+接收CSD、CID

define MMC_IO_CmdResp8nclk 0xC4 //

define MMC_IO_ReadDat8nck 0x03 //读MMC_BYTECNT字节

define MMC_IO_WriteDat8nck 0x01 //写MMC_BYTECNT字节

enum SdCardResponse {SDIOCmdError,SDIOCmdTrue};//命令响应判断
enum SDflag { SDTrue,SDFall}; //函数返回值:成功/失败

define SDIO_CLK_EN 18

define SDIO_CLK_RE 27

define Max_RepeatCount 100 //定义重复发送数据最大值

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

查看更多

关注者
0
被浏览
1.3k
1 个回答
isme
isme 认证专家 2022-11-07
冰镇大西瓜

可以看看这篇文章,可能对你有帮助。http://ask.winnermicro.com/article/36.html

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览