|
最近在研究SD卡的驱动,有几个问题弄不太明白,发CMD0回复0x01,然后发CMD1回复0x00应该是初始化正确了吧,下面我在发送CMD17,可是一直等不到0xfe,是什么原因呢,我已经调了很多天了,哪位高手帮我看一下我的程序,帮我分析一下哪里出了问题谢谢
#include"include.h"
u08 sector[512]={1,2,3};
/**************MMC片选***************/
void mmc_cs(u08 data)
{
if(data==1)
PORTB&=~(_BV(PB4));//mmc_cs(1)拉低cs信号线
else
PORTB|=_BV(PB4); //mmc_cs(0)抬高cs信号线
}
/**************MMC发送CMD**************/
u08 mmc_send_cmd(u08 *cmd)
{
u08 i=0,j=0,timeout=0;
u08 temp=0xff;
mmc_cs(0); //cs抬高
spi_send(0xff);
spi_send(0xff);
spi_send(0xff);
spi_send(0xff);
spi_send(0xff);
spi_send(0xff);
mmc_cs(1); //cs拉低
while(i++<6)
{
spi_send(*cmd++);
}
while((temp=spi_send(0xff))==0xff)
{
if(timeout++>200) return(temp);
}
mmc_cs(0); //cs抬高
return(temp);
}
/**************MMC初始化**********/
u08 mmc_init(void)
{
u32 arg=512;
u08 cmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
u08 a,timeout=0,temp=0x99,temp1=0x88,temp2=0xaa;
u16 i=0;
spi_init();
for(a=0;a<200;a++)
{ }
for(a=0;a<0x10;a++) //74个clock
{
spi_send(0XFF);
}
if((temp=mmc_send_cmd(cmd))!=0x01)
return (0xe0);//发送CMD0失败返回0xe0
//return (temp);//这里是测试需要,发送CMD0后成功发回0x01 (#1)
cmd[0]=0x41;
cmd[5]=0xff;
while((temp1=mmc_send_cmd(cmd))!=0x00)
{if(timeout++>0xfffe)
return(0xe1);//发送CMD1失败返回0xe1
}
//return(temp1);//这里是测试需要,发送CMD1后成功发回0x00
//发送cmd0返回0x01,cmd1返回0x00应该是初始化成功了吧????
spi_highspeed();//高速SPI
/* cmd[0]=59|0x40;
mmc_send_cmd(cmd);*/
cmd[0]=16|0x40;//main函数传递512给arg,CMD16设定读取块长为512字节
cmd[1]=arg>>24;
cmd[2]=arg>>16;
cmd[3]=arg>>8;
cmd[4]=arg;
cmd[5]=0x95;
temp2=mmc_send_cmd(cmd);
return(temp2);
//以上是发送CMD59和CMD16 ,但是我看SD SPEC上面说只有CMD0需要CRC校检,之后CRC校检被忽略掉,即为发送方无需关心和接收方忽略它,而
//而SD卡默认的read_bl_block是512,所以CMD16也应该是不必要的,不知道我说的对不对,但为了调试我还是加上了。
}
/*************读one sector数据**********/
u08 mmc_read_sector(u32 addr,u08 *buffer)
{
u16 i,j;
u08 k=0xaa,retry=0,m=0;
u08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
addr=addr<<9; //address*512
cmd[1]=((addr & 0xFF000000) >>24 );
cmd[2]=((addr & 0x00FF0000) >>16 );
cmd[3]=((addr & 0x0000FF00) >>8 );
cmd[4]=addr; //cmd[4]应该为0
do
{k=mmc_send_cmd(cmd);
retry++;
if(retry>100)return(0X44);//发送CMD17失败返回0X44
}
while(k!=0);
//return(k); //为了测试我在这里返回一个值看看cmd17是否被正确写入了
//这里可以返回0x00,应该是写CMD17正确了吧?
mmc_cs(1); //拉低cs
retry=0;
while((m=spi_send(0xff))!=0xfe)
{retry++;
if(retry>100)return(m);
}
//return(m); //读到0xfe成功 即返回m=0xfe,可惜一直等不到只是返回0xff T_T
for(i=0;i<512;i++)
{
*buffer++=spi_send(0xff);
}
spi_send(0xff);
spi_send(0xff);
mmc_cs(0);
return(0xce);//操作成功后返回0xce
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|