SDHC卡CMD41应答01。为什么?
已完成sdhc卡的初始化,但是为了简介,对sd发送命令函数进行修改,就是这样的修改造成cmd41不能成功。请大家看看。谢谢!!
1可实现CMD41和cmd55的函数
==================
1.1发送命令U08 SD_write_command (U08 *cmd)
{
U08 tmp = 0xff;
U16 Timeout = 0;
SD_Disable(); //SD_CS = HIGH
SD_write_byte(0xFF); //send 8 Clock Impulse
SD_Enable(); //SD_CS = LOW
//send 6 Byte Command
U08 a;
for (a = 0;a<0x06;a++)
{
SD_write_byte(*cmd++);
}
//get 16 bit response
while (tmp == 0xff)
{
tmp = SD_read_byte();//Only last 8 bit is used here.Read it out.
if (Timeout++ > 500){break;}
}
return(tmp);
}1.2cmd55和41反复发送 Timeout = 0;
//-------发卡初始化指令CMD55+ACMD41------------------------------
do
{
//-----2.1.3---- send CMD55---------
CMD=0x40+55;
CMD=0x00;CMD=0x00;
CMD=0x00;
CMD=0x00;
CMD=0x00;
r1 = SD_write_command(CMD);//不判断cmd55的应答
if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);} //ok输出==================
// if(r1!=0x01)
// {
//Uart_SendB(0xd3); Uart_SendB(r1);////将应答发送出来。---------zj-------------------
//return 0x55; //CMD55 Error!0x55
// }
//-----2.1.4---- send CMD41---------
CMD=0x40+41;
CMD=0x40;
CMD=0x00;
CMD=0x00;
CMD=0x00;
CMD=0x00;//网上有人对 CMD41初始化不成功,crc改成0x95成功了。
r1 = SD_write_command(CMD);
Timeout++;
if(Timeout>200)
{
if(SD_Debug_On==1){Uart_SendB(0xac);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xab);}//错误输出=============///将应答发送出来。---------zj-------------------
return 0x41; //超时则返回CMD41 Error!0x41
}
if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb); } //ok输出==================
}while(r1!=0);//进队CMD41响应判断2=不能应答的===============为什么?==
2.1 发送命令和应答函数//============================================================
//检测SD卡的响应
unsigned char SD_Response(void)
{
unsigned response=0xff;
unsigned int i=0;
while((i<=500))//& (response!=0xff))
{
response = SD_read_byte();
if(response==0x00)
break;
else if(response==0x01)
break;
else if(response==0x05)
break;
i++;
}
return response;
}
//================================================================
//发命令到SD卡
void SD_Cmd(unsigned char command, unsigned long argument, unsigned char CRC)
{
SD_Disable(); //SD_CS = HIGH
SD_write_byte(0xFF); //send 8 Clock Impulse
SD_Enable(); //SD_CS = LOW
SD_write_byte(command|0x40);
SD_write_byte(((unsigned char *)&argument));
SD_write_byte(((unsigned char *)&argument));
SD_write_byte(((unsigned char *)&argument));
SD_write_byte(((unsigned char *)&argument));
SD_write_byte(CRC);
}2.2cmd41和55do
{
//- 1)------ send CMD55---------
SD_Cmd(55,0,0xff);//cmd55
r1 =SD_Response();//不判断cmd55的应答
//if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);} //ok输出==================
if(r1!=0x01)
{
if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x55);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb);} ////将应答发送出来。---------zj-------------------
//return 0x55; //CMD55 Error!0x55
}
//- 2)-------- send CMD41---------
SD_Cmd(41,0x40000000,0x95);//cmd41//网上有人对 CMD41初始化不成功,crc改成0x95成功了。
r1 =SD_Response();//
Timeout++;
if(Timeout>250)
{
if(SD_Debug_On==1){Uart_SendB(0xac);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xab);}//错误输出=============///将应答发送出来。---------zj-------------------
SD_Disable();//SD_CS = high
return 0x41; //超时则返回CMD41 Error!0x41
}
//if(SD_Debug_On==1){Uart_SendB(0xbc);Uart_SendB(0x41);Uart_SendB(r1);Uart_SendB(Timeout);Uart_SendB(0xbb); } //ok输出==================
}while(r1!=0);//进队CMD41响应判断 仅是修改了命令发送方式,就造成了这样的情况。
之前的函数从反馈结果看 只需要循环发送 cmd55,41 3次就可实现。 ====================================================ing 3个不是绝对,这个和时间有点关系,我这边不管是SD2.0还是3.0的SDHC卡上电后第一次初始化都要发送几十至几百毫秒,其中CMD55 和 ACMD41占了80~90%的时间,估计有50~60 CMD55+ ACMD41这样的组合,但是上电后第二次初始化仅仅只需要发送一次就Busy =1。找找之前备份的代码,用排除法定位问题出在哪里吧。 mangoes 发表于 2012-8-11 08:13 static/image/common/back.gif
3个不是绝对,这个和时间有点关系,我这边不管是SD2.0还是3.0的SDHC卡上电后第一次初始化都要发送几十至几 ...
谢谢。
我的cmd0,cmd8都可以。
就是cmd41卡着了。采用原来的方法, 3-5次即可。 继续调试。看看原因。 jazsmile 发表于 2012-8-11 12:15 static/image/common/back.gif
谢谢。
我的cmd0,cmd8都可以。
刚刚测试了一下,ACMD41 的设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令参数有问题,改成这个试试0x51fc0000。 mangoes 发表于 2012-8-11 16:11 static/image/common/back.gif
刚刚测试了一下,ACMD41 的设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令 ...
谢谢。
修改了 命令函数
r1=SD_SendCommand_NoDeassert(41,0x40000000,0xff);
2--5次成功。
对 读和写都操作了,但是不能同时实现读和写的功能。郁闷!!//================================================================//
U08 SD_SendCommand_NoDeassert(U08cmd, U32 arg, U08crc)
{
unsigned char r1;
unsigned char Retry = 0;
//
SD_write_byte(0xff);
//片选端置低,选中SD卡
SD_Enable();
//发送
SD_write_byte(cmd | 0x40); //分别写入命令
SD_write_byte(arg >> 24);
SD_write_byte(arg >> 16);
SD_write_byte(arg >> 8);
SD_write_byte(arg);
SD_write_byte(crc);
//等待响应,或超时退出
while((r1 = SD_read_byte())==0xFF)
{
Retry++;
if(Retry > 200)
{
break;
}
}
//返回响应值
return r1;
} mangoes 发表于 2012-8-11 16:11 static/image/common/back.gif
刚刚测试了一下,ACMD41 的设置不正确的话无论发送多少ACMD41 Busy都不会等于1的,估计是你的命令 ...
能否测试一下我的功能。
我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。
我用的是sdhc卡
已经测试,1初始化成功。2,读成功;3写成功。
问题:读和写在一起就不行了。
能否在你板子上帮我测试下。谢谢。我将代码给你。
你的sd卡片选是多少? jazsmile 发表于 2012-8-11 16:27 static/image/common/back.gif
能否测试一下我的功能。
我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。
很抱歉,我的板子是STM32 SDIO模式的。至于SPI模式,这个没有调过。CMD17、18、24、25返回的Response是卡的状态寄存器的数值,可以通过这个状态寄存器配合原版SD2.0规格书来排查问题。这个寄存器可以记录很多错误的原因. jazsmile 发表于 2012-8-11 16:27 static/image/common/back.gif
能否测试一下我的功能。
我的读和写不能同时实现。能否我将代码发给你,你看看在你的板子上能否成功。
建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义 mangoes 发表于 2012-8-11 16:43 static/image/common/back.gif
很抱歉,我的板子是STM32 SDIO模式的。至于SPI模式,这个没有调过。CMD17、18、24、25返回的Response是卡 ...
谢谢!
我的读是 cmd17,
写是cmd25。 其它没有用。
返回都是符合sd协议的。因为我用串口监测每个步骤的返回和结果。 mangoes 发表于 2012-8-11 16:47 static/image/common/back.gif
建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义 ...
好的。我认真看看!
谢谢!! mangoes 发表于 2012-8-11 16:47 static/image/common/back.gif
建议看英文的。第84页,4.10.1 Card Status 章节 里面有详细的说明这个寄存器每个Bit的意义 ...
card status 怎么有32位。
实际在做的时候仅用了8位啊。 本帖最后由 mangoes 于 2012-8-11 18:40 编辑
jazsmile 发表于 2012-8-11 17:13 static/image/common/back.gif
card status 怎么有32位。
实际在做的时候仅用了8位啊。
你说的是高8位对吧?每个命令(command)以及响应(Response)长度都为48Bit(除R2外,即CMD2、CMD9、CMD10的响应),其中高8位为start bit + 方向 (1=command 0=reaponse) + CMD Index,中间32位为command或者reposne的参数.最后8为中有7位是CRC7 以及1Bit是Stop Bit,而返回类型为R1的所有response中间的32bit参数都是card status 寄存器。 {:smile:}{:smile:}{:smile:}{:smile:} 我最近在搞sdio读sd卡,sdio是模拟的,现在标准sd卡是读写没问题的,但是sdhc读总是出问题,卡上电第一次读是正确的,之后读就会出错,跟楼主的情况一样吗?楼主留个联系方式,请教一下 我qq1035548005般若
页:
[1]