单片机学习小组
直播中

王树林

7年用户 1630经验值
私信 关注

STM32F407使用SPI读写SD TF卡出现卡死情况怎么解决?

STM32F407使用SPI读写SD TF卡出现卡死情况怎么解决?

回帖(1)

李丕海

2022-2-17 09:38:12

问题描述:
使用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=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=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);//设置到高速模式       
}
举报

更多回帖

×
20
完善资料,
赚取积分