问题描述:
使用spi的TF卡模块,卡为京东联名的32g的HC卡,使用核心板外接模块,发现前面的初始和卡的检验可以通过,但读取不到扇区数,也不能读取扇区0,读取会卡死。核对了软硬件都毫无头绪,同样的代码在另一块407的带sd卡槽的板子上是读写没问题的。
解决:
由于使用的核心板和拓展模块,所以之间使用了不短的杜邦线,所以我怀疑是干扰,而且显然前面400k以下的速率设置和校验是没问题的,所以我怀疑是后面的高速模式才有问题。本着频率越低,越能抗干扰的朴素科学观。修改<400k初始化化之后切换为高速模式,如下位置(倒数第五行的SD_SPI_SpeedHigh();//高速)
u8 SD_Initialize(void)
{
u8 r1; // 存放SD卡的返回值
u16 retry; // 用来进行超时计数
u8 buf[4];
u16 i;
SD_SPI_Init(); //初始化IO
SD_SPI_SpeedLow(); //设置到低速模式
for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//发送最少74个脉冲 一个FF就是大于8个脉冲 这里大于80个脉冲了
retry=20;
do
{
r1=SD_SendCmd(CMD0,0,0x95);//进入IDLE状态
}while((r1!=0X01) && retry--);
SD_Type=0;//默认无卡
if(r1==0X01)
{
if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
{
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF); //Get trailing return value of R7 resp
if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V
{
retry=0XFFFE;
do
{
SD_SendCmd(CMD55,0,0X01); //发送CMD55
r1=SD_SendCmd(CMD41,0x40000000,0X01);//发送CMD41
}while(r1&&retry--);
if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始
{
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到OCR值
if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //检查CCS
else SD_Type=SD_TYPE_V2;
}
}
}else//SD V1.x/ MMC V3
{
SD_SendCmd(CMD55,0,0X01); //发送CMD55
r1=SD_SendCmd(CMD41,0,0X01); //发送CMD41
if(r1<=1)
{
SD_Type=SD_TYPE_V1;
retry=0XFFFE;
do //等待退出IDLE模式
{
SD_SendCmd(CMD55,0,0X01); //发送CMD55
r1=SD_SendCmd(CMD41,0,0X01);//发送CMD41
}while(r1&&retry--);
}else//MMC卡不支持CMD55+CMD41识别
{
SD_Type=SD_TYPE_MMC;//MMC V3
retry=0XFFFE;
do //等待退出IDLE模式
{
r1=SD_SendCmd(CMD1,0,0X01);//发送CMD1
}while(r1&&retry--);
}
if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//错误的卡
}
}
SD_DisSelect();//取消片选
SD_SPI_SpeedHigh();//高速
if(SD_Type)return 0;
else if(r1)return r1;
return 0xaa;//其他错误
}
进入这个函数,修改慢一点,修改为1/4,之前是1/2(SPI_SPEED_2)。
//SD卡正常工作的时候,可以高速了
void SD_SPI_SpeedHigh(void)
{
SPI1_SetSpeed(SPI_SPEED_4);//设置到高速模式
}