打印

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

[复制链接]
7954|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zxb1717|  楼主 | 2008-6-10 11:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 
}

相关帖子

沙发
xwj| | 2008-6-10 11:59 | 只看该作者

呵呵,其实最快捷的方法是用逻辑分析仪看看别人是怎么做

当然,前提是有别人先做好的:-)

使用特权

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

请热心的大侠帮忙看看

我的初始化时钟大约在150K,应该够慢了,再慢的100K也试了,还是返回0x01

使用特权

评论回复
地板
zxb1717|  楼主 | 2008-6-10 13:14 | 只看该作者

难道没有高手做过类似的项目吗

帮帮忙高手们,给个建议吧

使用特权

评论回复
5
zxb1717|  楼主 | 2008-6-10 15:40 | 只看该作者

难道没有人做过吗

自己顶起来,等待中......

使用特权

评论回复
6
古道热肠| | 2008-6-10 15:53 | 只看该作者

给您一个建议

别上来就弄4G的SD卡,先整个512K的SD卡测试一下,看看您的驱动程序能否用起来,小容量的SD卡驱动能用的很好找,可以参考一下网友"章其波"先生的例程
if(容量<512K测试OK)

您的驱动要改一改,作兼容性更改,(印象中2G以内是一个模式,2G以上是另外一套模式[命令]了)

else
{
您的驱动彻底不能用
}

使用特权

评论回复
7
zxb1717|  楼主 | 2008-6-10 16:07 | 只看该作者

先谢谢古道热肠

手头没有512K啊,只有一个2G和一个4G的。能否说的稍微详细一点,2G以上是什么模式,继续等待中......

使用特权

评论回复
8
zxb1717|  楼主 | 2008-6-10 16:10 | 只看该作者

请问哪里有"章其波"先生的例程?

能否告诉我哪里有"章其波"先生的例程。百度上搜都不是

使用特权

评论回复
9
xujunchen| | 2008-6-10 16:26 | 只看该作者

与容量大小无关!

使用特权

评论回复
10
zxb1717|  楼主 | 2008-6-10 16:34 | 只看该作者

再问一下用SPI是否可讀寫SDHC的卡C

我的4G的KingSton的SDHC card,用SPI能进行读写操作吗?

使用特权

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

自己顶,继续等

使用特权

评论回复
12
zxb1717|  楼主 | 2008-6-10 17:13 | 只看该作者

关于发送74个同步时钟的问题

网上给出的例程中,有的发送74个同步时钟时片选是关掉的,而有的是使能的,请问谁知道到底是关掉还是使能啊?

使用特权

评论回复
13
wlsui| | 2008-6-10 18:51 | 只看该作者

4G及4G以上的卡采用的是SDHC协议(SD2.0),

4G及4G以上的卡采用的是SDHC协议(SD2.0),而2G及2G以下的卡采用的是SD1.0协议,两者协议略有不同
所以,如果你要想读写4G卡,必须要先对SD1.0的驱动做些改动

使用特权

评论回复
14
zxb1717|  楼主 | 2008-6-10 19:42 | 只看该作者

多谢wlsui

但是不知道哪里能找到SDHC协议(SD2.0),网上的都是SD1.0的,能否请wlsui提示一下怎么改动,你有SDHC协议(SD2.0)吗,有的话能否给我一份,谢谢。谢谢大家关注,我实在是没办法了

使用特权

评论回复
15
zxb1717|  楼主 | 2008-6-10 20:16 | 只看该作者

顺便再问一下,SD卡内部的地址分配情况

如果要读取大小为2G的SD卡内部开始的512字节,地址是不是:0x00000000~~0x000001FF

使用特权

评论回复
16
huangqi412| | 2008-6-10 20:47 | 只看该作者

大容量的不同

使用特权

评论回复
17
zxb1717|  楼主 | 2008-6-10 21:06 | 只看该作者

能否请huangqi412说的详细一点

不同在什么地方,比如2G和4G的,如果都是从一开始写512字节,差别在什么地方

使用特权

评论回复
18
zxb1717|  楼主 | 2008-6-11 08:50 | 只看该作者

各位路过的大侠帮忙看看吧

在此谢过各位了,指点指点吧

使用特权

评论回复
19
zxb1717|  楼主 | 2008-6-11 10:29 | 只看该作者

SDHC card 的协议谁有能给我一份吗

使用特权

评论回复
20
zxb1717|  楼主 | 2008-6-11 10:37 | 只看该作者

找到SD2.0协议了,谁要用我发给他

其他的问题希望其他大侠帮忙解答,照顾一下菜鸟吧,谢谢

使用特权

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

本版积分规则

31

主题

231

帖子

1

粉丝