打印

4GB的SD卡的初始化没有成功,热心的高手帮忙看看

[复制链接]
1636|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zxb1717|  楼主 | 2008-6-10 13:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
SD卡, GB, 4G, se, TE


看了很多资料,例程,但还是没有成功,可能哪里出了问题没发现,请大家帮我看看。以下是关键的3个函数,CMD0和CMD55返回的响应是0x01,但ACMD41返回的响应还是0x01,应该是0才对,但是怎么调试都不行,大侠帮看一下吧,先在此谢过了!


BYTE SD_SendCmd(BYTE cmd, BYTE *param, BYTE resptype, BYTE *resp)
{
    WORD i;                            //所有SD卡命令都是6字节长
    BYTE xdata tmp,rlen,Cmd_Buf[6];
    char j;

    if(cmd == CMD0)
        Cmd_Buf[0] = 0x95;                // 发送CRC校验码,只用于第1个命令(command0=40 00 00 00 00 95) 
    else                                    //起始位为0(bit47),传输位为1(bit46)
        Cmd_Buf[0] = 0xFF;
    for(j = 3;j >=0;j --)
    {
        Cmd_Buf[j+1] = param[j];          //param[j]
    }
    Cmd_Buf[5] = (cmd & 0x3F) | 0x40;
    if(cmd == CMD0)                        //先发送74个以上的时钟,为了使SD卡同步
    {    
        SET_Slave_select(0);
//        EZUSB_Delay(1);
        for(i=0;i<10;i++)
            SPI_Send_Byte(0xFF);
    }
    else
    {
        SET_Slave_select(0);
        SPI_Send_Byte(0xFF);
    }
    SET_Slave_select(2);
                    //片选SPI从机
    SPI_Send_Byte(Cmd_Buf[5]);
    SPI_Send_Byte(Cmd_Buf[4]);
    SPI_Send_Byte(Cmd_Buf[3]);
    SPI_Send_Byte(Cmd_Buf[2]);
    SPI_Send_Byte(Cmd_Buf[1]);
    SPI_Send_Byte(Cmd_Buf[0]);

    i = 0;
    do                                      // 等待响应,响应的最高位为0 
    {                                    //Wait for a response,a response is a start bit(zero)  
        tmp = 0xFF;
        tmp = SPI_Rec_Byte();            //在没收到响应令牌之前,tmp=0xFF,因此tmp & 0x80==1,
           i++;
    }
    while (((tmp & 0x80) != 0) && (i < SD_CMD_TIMEOUT));    //收到响应以后由于响应最高位是0,因此tmp & 0x80==0
    
    if (i >= SD_CMD_TIMEOUT)            //超时
    {                                                 
//        SPI_CS_Deassert();                //释放总线
        TD_Poll(0x15);
        EZUSB_Delay(2000);
        TD_Poll(tmp);
        EZUSB_Delay(2000);
        SET_Slave_select(0);
        return SD_ERR_CMD_TIMEOUT;        // 返回命令超时 return response timeout of command 
    }

    rlen = 0;
    switch (resptype)                    //根据不同的命令,得到不同的响应长度 
     {                                    //according various command,get the various response length 
          case R1:
            case R1B: 
            rlen = 1;  
        break;
                
                 case R2: 
            rlen = 2;     
        break;
                
           case R3: 
            rlen = 5;     
        break;
                
        default: 
            rlen = 1;
//            SPI_Send_Byte(0xFF);
            
            SPI_CS_Deassert();
            return SD_ERR_CMD_RESPTYPE;     // 返回命令响应类型错误 return error of command response type 
        break;
    }
    
//    EZUSB_Delay(1);
    *resp = tmp;            
    for (j = rlen - 1; j >= 0; j--)
    {
          SPI_Send_Byte(0xFF);                //resp的最高字节保存响应令牌Rx,其他字节装入0xFF
//        SPI_Send_Byte(0xFF);        // 发送周期的最后发送8clock  at the last recycle,clock out 8 clock 
    }
    SET_Slave_select(0);    
    
    return SD_NO_ERR;                 // 返回执行成功 return perform sucessfully 
}


//////////复位/////////////
BYTE SD_ResetSD(void)        /////
{
    BYTE  xdata param[4] = {0,0,0,0},ret,resp;
    
    ret = SD_SendCmd(CMD0, param, CMD0_R, &resp);    /* 复位命令 command that reset sd card */
    if(ret != SD_NO_ERR)
    {
        
        return 1;
    }
    if(resp != 0x01)
    {
        TD_Poll(0x11); 
        EZUSB_Delay(2000);
        TD_Poll(resp); 
        EZUSB_Delay(2000);
        return 1;
    }
    return SD_NO_ERR;
}
///////////激活/////////////////
BYTE SD_Active(void)
{
    BYTE xdata param[4] = {0,0,0,0},*resp1,*resp2,ret;
    BYTE xdata i;

     ret = SD_SendCmd(CMD55, param, CMD55_R, resp1);        // 后续命令为一个应用命令 
        if (ret != SD_NO_ERR)
        {
               TD_Poll(0x21); 
            EZUSB_Delay(2000);
               return ret;                        // command that the followed commnad is a specific application
        }    
                                         
        if (*resp1 & 0x01 != 1 )    //CMD55响应值是0x01
        {
             TD_Poll(0x22); 
            EZUSB_Delay(2000);
//            TD_Poll(*resp); 
//            EZUSB_Delay(2000);
             return SD_ERR_CMD_RESP;                    // 响应错误 response is error 
        }
        
    i = 0;
    do                         // 循环发出CMD55+ACMD41, 查询卡的状态
    {  
        ret = SD_SendCmd(ACMD41, param, ACMD41_R, resp2);
        
        if (ret != SD_NO_ERR)
        {
            TD_Poll(0x23); 
            EZUSB_Delay(2000);
               return ret;
          }
        i++;
    }while ((i < 200)&& (*resp2 != 0));/* 如果响应R1的最低位Idle位为1,则继续循环 */

    if (i >= 200)
    {
        TD_Poll(0x24); 
        EZUSB_Delay(2000);
        TD_Poll(*resp2); 
        EZUSB_Delay(2000);
        return SD_ERR_TIMEOUT_WAITIDLE;                    // 超时,返回错误 time out,return error 
    } 
                                                   
    if (*resp2 != 0)
        return SD_ERR_CMD_RESP;                    //响应错误 response is error 
        
    return SD_NO_ERR;        // 读出寄存器内容 read the content of the register 
}
 
 

相关帖子

沙发
zxb1717|  楼主 | 2008-6-10 14:06 | 只看该作者

哪位大侠路过这里给我个建议吧

以前做过类似项目的大侠给我一个建议吧

使用特权

评论回复
板凳
zxb1717|  楼主 | 2008-6-10 17:19 | 只看该作者

看来这里没有高手路过啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

231

帖子

1

粉丝