找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3648|回复: 0
收起左侧

STM32F103C8T6 读写SD卡 f_mount()返回错误,求助

[复制链接]
ID:70069 发表于 2020-4-24 10:04 | 显示全部楼层 |阅读模式
本帖最后由 benclee 于 2020-4-24 10:06 编辑

用的正点原子的代码
执行f_mount(fs[0],"0:",1)时返回FR_DISK_ERR
跟进去,res = find_volume(&fs, &path, 0),这里返回1
再跟进去fmt = check_fs(fs, bsect);/* 加载0扇区并检查fat是否是 sfd 引导扇区 */这里返回3
static
BYTE check_fs (        /* 0:FAT boor sector, 1:Valid boor sector but not FAT, 2:Not a boot sector, 3:Disk error */
        FATFS* fs,        /* File system object */
        DWORD sect        /* Sector# (lba) to check if it is an FAT boot record or not */
)
{
        fs->wflag = 0; fs->winsect = 0xFFFFFFFF;        /* Invaidate window */
        if (move_window(fs, sect) != FR_OK)                        /* Load boot record */
                printf("move_win%d\r\n",(move_window(fs,sect)));//******************************************
                return 3;

        if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)        /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */
                return 2;

        if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146)                /* Check "FAT" string */
                return 0;
        if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)        /* Check "FAT" string */
                return 0;

        return 1;
}

再跟进去if (move_window(fs, sect) != FR_OK)        move_window()返回1
static
FRESULT move_window (
        FATFS* fs,                /* File system object */
        DWORD sector        /* Sector number to make appearance in the fs->win[] */
)
{
        if (sector != fs->winsect) {        /* Changed current window */
#if !_FS_READONLY
                        printf("sync_win%d\r\n",sync_window(fs));//*********************************
                if (sync_window(fs) != FR_OK)
                        return FR_DISK_ERR;
#endif
                if (disk_read(fs->drv, fs->win, sector, 1))
                        printf("disk_read%d\r\n",disk_read(fs->drv, fs->win, sector, 1));//****************************
                        return FR_DISK_ERR;
                fs->winsect = sector;
        }

        return FR_OK;
}

再到disk_read(fs->drv, fs->win, sector, 1)返回1
DRESULT disk_read (
        BYTE pdrv,                /* Physical drive nmuber (0..) */
        BYTE *buff,                /* Data buffer to store read data */
        DWORD sector,        /* Sector address (LBA) */
        UINT count                /* Number of sectors to read (1..128) */
)
{
        u8 res=0;
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误                          
        switch(pdrv)
        {
                case SD_CARD://SD卡
                        res=SD_ReadDisk(buff,sector,count);
      printf("SD_readdisk%d\r\n",res);               
                         if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
                        {
                                SD_SPI_SpeedLow();
                                SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
                                SD_SPI_SpeedHigh();
                        }
                        break;
//                case EX_FLASH://外部flash
//                        for(;count>0;count--)
//                        {
//                                SPI_Flash_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
//                                sector++;
//                                buff+=FLASH_SECTOR_SIZE;
//                        }
//                        res=0;
//                        break;
                default:
                        res=1;
        }
   //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res==0x00)return RES_OK;         
    else return RES_ERROR;           
}

进去后SD_ReadDisk(buff,sector,count);返回127
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
{
        u8 r1;
        if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址
        if(cnt==1)
        {
                r1=SD_SendCmd(CMD17,sector,0X01);//读命令
                printf("send cmd17%d\r\n",r1);//**********************************
                if(r1==0)//指令发送成功
                {
                        r1=SD_RecvData(buf,512);//接收512个字节           
                }
        }else
        {
                r1=SD_SendCmd(CMD18,sector,0X01);//连续读命令
                do
                {
                        r1=SD_RecvData(buf,512);//接收512个字节         
                        buf+=512;  
                }while(--cnt && r1==0);         
                SD_SendCmd(CMD12,0,0X01);        //发送停止命令
        }   
        SD_DisSelect();//取消片选
        printf("send cmd18%d\r\n",r1);//**********************************
        return r1;//
}

r1=SD_SendCmd(CMD17,sector,0X01);//读命令这里返回127
到这里不知道怎么查了。下面是SD_SendCmd()函数。
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
{
    u8 r1;        
        u8 Retry=0;
        SD_DisSelect();//取消上次片选
        if(SD_Select())return 0XFF;//片选失效
        //发送
    SD_SPI_ReadWriteByte(cmd | 0x40);//分别写入命令
    SD_SPI_ReadWriteByte(arg >> 24);
    SD_SPI_ReadWriteByte(arg >> 16);
    SD_SPI_ReadWriteByte(arg >> 8);
    SD_SPI_ReadWriteByte(arg);         
    SD_SPI_ReadWriteByte(crc);
        if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
    //等待响应,或超时退出
        Retry=0X1F;
        do
        {
                r1=SD_SPI_ReadWriteByte(0xFF);
        }while((r1&0X80) && Retry--);         
        //返回状态值
    return r1;
}



u8 SD_SPI_ReadWriteByte(u8 data){
        return SPI1_ReadWriteByte(data);
}
u8 SPI1_ReadWriteByte(u8 TxData)
{                        u8 retry=0;        
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
        {
           retry++;
          if(retry>200)
          return 0;
        }
   SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
   retry=0;
   //        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位                    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
      {
        retry++;
        if(retry>200)
        return 0;
      }
     return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}                                                                                             

大神帮忙看看哪里出问题了。谢谢


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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