本帖最后由 benclee 于 2020-4-24 10:06 編輯
用的正點原子的代碼
執(zhí)行f_mount(fs[0],"0:",1)時返回FR_DISK_ERR
跟進去,res = find_volume(&fs, &path, 0),這里返回1
再跟進去fmt = check_fs(fs, bsect);/* 加載0扇區(qū)并檢查fat是否是 sfd 引導扇區(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;
}
再跟進去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卡操作失敗的時候如果不執(zhí)行下面的語句,可能導致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;//轉換為字節(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個字節(jié)
}
}else
{
r1=SD_SendCmd(CMD18,sector,0X01);//連續(xù)讀命令
do
{
r1=SD_RecvData(buf,512);//接收512個字節(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()函數。
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);//分別寫入命令
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--);
//返回狀態(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標志位設置與否:發(fā)送緩存空標志位
{
retry++;
if(retry>200)
return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通過外設SPIx發(fā)送一個數據
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最近接收的數據
}
大神幫忙看看哪里出問題了。謝謝
|