搜索
bottom↓
回复: 16

SDHC卡CMD41应答01。为什么?

[复制链接]

出0入0汤圆

发表于 2012-8-10 20:39:00 | 显示全部楼层 |阅读模式
已完成sdhc卡的初始化,但是为了简介,对sd发送命令函数进行修改,就是这样的修改造成cmd41不能成功。

请大家看看。谢谢!!



1可实现CMD41和cmd55的函数
==================
1.1发送命令
  1. U08 SD_write_command (U08 *cmd)
  2. {
  3.         U08 tmp = 0xff;
  4.         U16 Timeout = 0;

  5.         SD_Disable();        //SD_CS = HIGH
  6.         SD_write_byte(0xFF); //send 8 Clock Impulse
  7.         SD_Enable();         //SD_CS = LOW   

  8.         //send 6 Byte Command
  9.     U08 a;
  10.         for (a = 0;a<0x06;a++)  
  11.                 {
  12.                   SD_write_byte(*cmd++);
  13.                 }

  14.         //get 16 bit response
  15.         while (tmp == 0xff)       
  16.                 {
  17.                 tmp = SD_read_byte();  //Only last 8 bit is used here.Read it out.
  18.                 if (Timeout++ > 500){break;}
  19.                 }
  20.         return(tmp);
  21. }
复制代码
1.2cmd55和41反复发送
  1. Timeout = 0;
  2.             //-------发卡初始化指令CMD55+ACMD41------------------------------
  3.                do
  4.                {
  5.                                 //-----2.1.3---- send CMD55  ---------
  6.                         CMD[0]=0x40+55;
  7.                         CMD[1]=0x00;CMD[2]=0x00;
  8.                         CMD[3]=0x00;
  9.                         CMD[4]=0x00;
  10.                         CMD[5]=0x00;
  11.                         r1 = SD_write_command(CMD);//不判断cmd55的应答
  12.                         if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);}                        //ok输出==================
  13.                        
  14.                // if(r1!=0x01)
  15.                // {
  16.                //  Uart_SendB(0xd3); Uart_SendB(r1);////将应答发送出来。---------zj-------------------
  17.                //  return 0x55; //CMD55 Error!  0x55
  18.                // }

  19.                         //-----2.1.4---- send CMD41  ---------

  20.                         CMD[0]=0x40+41;
  21.                         CMD[1]=0x40;
  22.                         CMD[2]=0x00;
  23.                         CMD[3]=0x00;
  24.                         CMD[4]=0x00;
  25.                         CMD[5]=0x00;//网上有人对 CMD41初始化不成功,crc改成0x95成功了。
  26.                 r1 = SD_write_command(CMD);
  27.                         Timeout++;
  28.                         if(Timeout>200)   
  29.                         {
  30.                                                 if(SD_Debug_On==1){Uart_SendB(0xac);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xab);}//错误输出=============///将应答发送出来。---------zj-------------------
  31.                                                 return 0x41; //超时则返回CMD41 Error!  0x41
  32.                         }
  33.                         if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);        }                //ok输出==================               
  34.                }while(r1!=0);//进队CMD41响应判断
复制代码
2=不能应答的===============为什么?==

2.1 发送命令和应答函数
  1. //============================================================
  2. //检测SD卡的响应
  3. unsigned char SD_Response(void)
  4. {
  5.     unsigned response=0xff;
  6.         unsigned int i=0;
  7.    
  8.     while((i<=500))//& (response!=0xff))
  9.     {
  10.         response = SD_read_byte();
  11.                  
  12.         if(response==0x00)
  13.         break;
  14.         else if(response==0x01)
  15.         break;
  16.                 else if(response==0x05)
  17.         break;
  18.          
  19.         i++;
  20.     }
  21.     return response;
  22. }
  23. //================================================================
  24. //发命令到SD卡
  25. void SD_Cmd(unsigned char command, unsigned long argument, unsigned char CRC)
  26. {
  27.         SD_Disable();        //SD_CS = HIGH
  28.         SD_write_byte(0xFF); //send 8 Clock Impulse
  29.        
  30.         SD_Enable();         //SD_CS = LOW  
  31.     SD_write_byte(command|0x40);
  32.     SD_write_byte(((unsigned char *)&argument)[0]);
  33.     SD_write_byte(((unsigned char *)&argument)[1]);
  34.     SD_write_byte(((unsigned char *)&argument)[2]);
  35.     SD_write_byte(((unsigned char *)&argument)[3]);
  36.     SD_write_byte(CRC);
  37. }
复制代码
2.2  cmd41和55
  1. do
  2.                {
  3.                         //- 1)------ send CMD55  ---------

  4.                         SD_Cmd(55,0,0xff);//cmd55
  5.                         r1 =SD_Response();//不判断cmd55的应答
  6.                         //if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);}                        //ok输出==================
  7.                        
  8.                if(r1!=0x01)
  9.                 {
  10.                if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);}        ////将应答发送出来。---------zj-------------------
  11.                //  return 0x55; //CMD55 Error!  0x55
  12.                }

  13.                         //- 2)-------- send CMD41  ---------
  14.                         SD_Cmd(41,0x40000000,0x95);//cmd41  //网上有人对 CMD41初始化不成功,crc改成0x95成功了。
  15.                         r1 =SD_Response();//

  16.                         Timeout++;
  17.                         if(Timeout>250)   
  18.                         {
  19.                                                 if(SD_Debug_On==1){Uart_SendB(0xac);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xab);}//错误输出=============///将应答发送出来。---------zj-------------------
  20.                                                  SD_Disable();//SD_CS = high
  21.                                                 return 0x41; //超时则返回CMD41 Error!  0x41
  22.                         }
  23.                         //if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);        }                //ok输出==================               
  24.                }while(r1!=0);//进队CMD41响应判断
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-8-10 20:40:24 | 显示全部楼层
仅是修改了命令发送方式,就造成了这样的情况。

之前的函数从反馈结果看 只需要循环发送 cmd55,41 3次就可实现。

出0入0汤圆

 楼主| 发表于 2012-8-10 23:46:14 | 显示全部楼层
====================================================ing

出0入0汤圆

发表于 2012-8-11 08:13:31 | 显示全部楼层
3个不是绝对,这个和时间有点关系,我这边不管是SD2.0还是3.0的SDHC卡上电后第一次初始化都要发送几十至几百毫秒,其中CMD55 和 ACMD41占了80~90%的时间,估计有50~60 CMD55+ ACMD41这样的组合,但是上电后第二次初始化仅仅只需要发送一次就Busy =  1。找找之前备份的代码,用排除法定位问题出在哪里吧。

出0入0汤圆

 楼主| 发表于 2012-8-11 12:15:18 | 显示全部楼层
mangoes 发表于 2012-8-11 08:13
3个不是绝对,这个和时间有点关系,我这边不管是SD2.0还是3.0的SDHC卡上电后第一次初始化都要发送几十至几 ...

谢谢。

我的cmd0,cmd8都可以。

就是cmd41卡着了。采用原来的方法, 3-5次即可。

出0入0汤圆

 楼主| 发表于 2012-8-11 12:16:24 | 显示全部楼层
继续调试。看看原因。

出0入0汤圆

发表于 2012-8-11 16:11:02 | 显示全部楼层
jazsmile 发表于 2012-8-11 12:15
谢谢。

我的cmd0,cmd8都可以。

刚刚测试了一下,ACMD41 的[15:23]设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令参数有问题,改成这个试试0x51fc0000。

出0入0汤圆

 楼主| 发表于 2012-8-11 16:24:42 | 显示全部楼层
mangoes 发表于 2012-8-11 16:11
刚刚测试了一下,ACMD41 的[15:23]设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令 ...

谢谢。

修改了 命令函数
r1=SD_SendCommand_NoDeassert(41,0x40000000,0xff);
2--5次成功。

对 读和写都操作了,但是不能同时实现读和写的功能。郁闷!!
  1. //================================================================//
  2. U08 SD_SendCommand_NoDeassert(U08  cmd, U32 arg, U08  crc)
  3. {
  4.     unsigned char r1;
  5.     unsigned char Retry = 0;

  6.     //
  7.     SD_write_byte(0xff);
  8.     //片选端置低,选中SD卡
  9.     SD_Enable();

  10.     //发送
  11.     SD_write_byte(cmd | 0x40);                         //分别写入命令
  12.     SD_write_byte(arg >> 24);
  13.     SD_write_byte(arg >> 16);
  14.     SD_write_byte(arg >> 8);
  15.     SD_write_byte(arg);
  16.     SD_write_byte(crc);
  17.    
  18.     //等待响应,或超时退出
  19.     while((r1 = SD_read_byte())==0xFF)
  20.     {
  21.         Retry++;
  22.         if(Retry > 200)
  23.         {
  24.             break;
  25.         }
  26.     }
  27.     //返回响应值
  28.     return r1;
  29. }
复制代码

出0入0汤圆

 楼主| 发表于 2012-8-11 16:27:24 | 显示全部楼层
mangoes 发表于 2012-8-11 16:11
刚刚测试了一下,ACMD41 的[15:23]设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令 ...

能否测试一下我的功能。

我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。

我用的是sdhc卡
已经测试,1初始化成功。2,读成功;3写成功。

问题:读和写在一起就不行了。


能否在你板子上帮我测试下。谢谢。我将代码给你。

你的sd卡片选是多少?

出0入0汤圆

发表于 2012-8-11 16:43:37 | 显示全部楼层
jazsmile 发表于 2012-8-11 16:27
能否测试一下我的功能。

我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。

很抱歉,我的板子是STM32 SDIO模式的。至于SPI模式,这个没有调过。CMD17、18、24、25返回的Response是卡的状态寄存器的数值,可以通过这个状态寄存器配合原版SD2.0规格书来排查问题。这个寄存器可以记录很多错误的原因.

出0入0汤圆

发表于 2012-8-11 16:47:34 | 显示全部楼层
jazsmile 发表于 2012-8-11 16:27
能否测试一下我的功能。

我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。

建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义

出0入0汤圆

 楼主| 发表于 2012-8-11 16:47:58 | 显示全部楼层
mangoes 发表于 2012-8-11 16:43
很抱歉,我的板子是STM32 SDIO模式的。至于SPI模式,这个没有调过。CMD17、18、24、25返回的Response是卡 ...

谢谢!

我的读是 cmd17,

写是cmd25。 其它没有用。

返回都是符合sd协议的。因为我用串口监测每个步骤的返回和结果。

出0入0汤圆

 楼主| 发表于 2012-8-11 16:48:45 | 显示全部楼层
mangoes 发表于 2012-8-11 16:47
建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义 ...

好的。我认真看看!

谢谢!!

出0入0汤圆

 楼主| 发表于 2012-8-11 17:13:30 | 显示全部楼层
mangoes 发表于 2012-8-11 16:47
建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义 ...

card status 怎么有32位。

实际在做的时候仅用了8位啊。

出0入0汤圆

发表于 2012-8-11 18:34:27 | 显示全部楼层
本帖最后由 mangoes 于 2012-8-11 18:40 编辑
jazsmile 发表于 2012-8-11 17:13
card status 怎么有32位。

实际在做的时候仅用了8位啊。


你说的是高8位对吧?每个命令(command)以及响应(Response)长度都为48Bit(除R2外,即CMD2、CMD9、CMD10的响应),其中高8位为start bit[47] + 方向[46] (1=command 0=reaponse) + CMD Index,中间32位为command或者reposne的参数.最后8为中有7位是CRC7 以及1Bit是Stop Bit,而返回类型为R1的所有response中间的32bit参数都是card status 寄存器。

出0入0汤圆

发表于 2012-9-24 13:37:06 | 显示全部楼层

出0入0汤圆

发表于 2013-4-11 11:29:32 | 显示全部楼层
我最近在搞sdio读sd卡,sdio是模拟的,现在标准sd卡是读写没问题的,但是sdhc读总是出问题,卡上电第一次读是正确的,之后读就会出错,跟楼主的情况一样吗?楼主留个联系方式,请教一下 我qq1035548005般若
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表