找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4340|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

STM32F103C8T6 讀寫(xiě)SD卡 f_mount()返回錯(cuò)誤,求助

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:70069 發(fā)表于 2020-4-24 10:04 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 benclee 于 2020-4-24 10:06 編輯

用的正點(diǎn)原子的代碼
執(zhí)行f_mount(fs[0],"0:",1)時(shí)返回FR_DISK_ERR
跟進(jìn)去,res = find_volume(&fs, &path, 0),這里返回1
再跟進(jìn)去fmt = check_fs(fs, bsect);/* 加載0扇區(qū)并檢查fat是否是 sfd 引導(dǎo)扇區(qū) */這里返回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;
}

再跟進(jìn)去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,否則返回參數(shù)錯(cuò)誤                          
        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卡操作失敗的時(shí)候如果不執(zhí)行下面的語(yǔ)句,可能導(dǎo)致SPI讀寫(xiě)異常
                        {
                                SD_SPI_SpeedLow();
                                SD_SPI_ReadWriteByte(0xff);//提供額外的8個(gè)時(shí)鐘
                                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的返回值轉(zhuǎn)成ff.c的返回值
    if(res==0x00)return RES_OK;         
    else return RES_ERROR;           
}

進(jìn)去后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;//轉(zhuǎn)換為字節(jié)地址
        if(cnt==1)
        {
                r1=SD_SendCmd(CMD17,sector,0X01);//讀命令
                printf("send cmd17%d\r\n",r1);//**********************************
                if(r1==0)//指令發(fā)送成功
                {
                        r1=SD_RecvData(buf,512);//接收512個(gè)字節(jié)           
                }
        }else
        {
                r1=SD_SendCmd(CMD18,sector,0X01);//連續(xù)讀命令
                do
                {
                        r1=SD_RecvData(buf,512);//接收512個(gè)字節(jié)         
                        buf+=512;  
                }while(--cnt && r1==0);         
                SD_SendCmd(CMD12,0,0X01);        //發(fā)送停止命令
        }   
        SD_DisSelect();//取消片選
        printf("send cmd18%d\r\n",r1);//**********************************
        return r1;//
}

r1=SD_SendCmd(CMD17,sector,0X01);//讀命令這里返回127
到這里不知道怎么查了。下面是SD_SendCmd()函數(shù)。
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
{
    u8 r1;        
        u8 Retry=0;
        SD_DisSelect();//取消上次片選
        if(SD_Select())return 0XFF;//片選失效
        //發(fā)送
    SD_SPI_ReadWriteByte(cmd | 0x40);//分別寫(xiě)入命令
    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
    //等待響應(yīng),或超時(shí)退出
        Retry=0X1F;
        do
        {
                r1=SD_SPI_ReadWriteByte(0xFF);
        }while((r1&0X80) && Retry--);         
        //返回狀態(tài)值
    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標(biāo)志位設(shè)置與否:發(fā)送緩存空標(biāo)志位
        {
           retry++;
          if(retry>200)
          return 0;
        }
   SPI_I2S_SendData(SPI1, TxData); //通過(guò)外設(shè)SPIx發(fā)送一個(gè)數(shù)據(jù)
   retry=0;
   //        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//檢查指定的SPI標(biāo)志位設(shè)置與否:接受緩存非空標(biāo)志位                    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
      {
        retry++;
        if(retry>200)
        return 0;
      }
     return SPI_I2S_ReceiveData(SPI1); //返回通過(guò)SPIx最近接收的數(shù)據(jù)
}                                                                                             

大神幫忙看看哪里出問(wèn)題了。謝謝


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表