Stm32 f_mount()返回FA_DISK_ERR

Stm32 f_mount()返回FA_DISK_ERR,stm32,sd-card,spi,cubemx,Stm32,Sd Card,Spi,Cubemx,在收到大家的建议后,我对源代码做了一些修改。为了将FATFSAPI与SPI接口连接起来,我遵循了以下代码 并相应地更改了我的用户\u diskio.c 完成所有这些操作后,我的SD卡也会返回FA\u DISK\u ERROR 我换了SD卡插槽和SD卡。但一切都没有改变 我的用户\u diskio.c如下所示: #include <string.h> #include "ff_gen_drv.h" #include "fatfs_sd.h" /* Private typedef --

在收到大家的建议后,我对源代码做了一些修改。为了将FATFSAPI与SPI接口连接起来,我遵循了以下代码

并相应地更改了我的
用户\u diskio.c

完成所有这些操作后,我的SD卡也会返回
FA\u DISK\u ERROR

我换了SD卡插槽和SD卡。但一切都没有改变

我的
用户\u diskio.c
如下所示:

#include <string.h>
#include "ff_gen_drv.h"
#include "fatfs_sd.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;

/* USER CODE END DECL */

/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize (BYTE pdrv);
DSTATUS USER_status (BYTE pdrv);
DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
  DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);  
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
  DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
#endif /* _USE_IOCTL == 1 */

Diskio_drvTypeDef  USER_Driver =
{
  USER_initialize,
  USER_status,
  USER_read, 
#if  _USE_WRITE
  USER_write,
#endif  /* _USE_WRITE == 1 */  
#if  _USE_IOCTL == 1
  USER_ioctl,
#endif /* _USE_IOCTL == 1 */
};

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Initializes a Drive
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_initialize (
    BYTE pdrv           /* Physical drive nmuber to identify the drive */
)
{
  /* USER CODE BEGIN INIT */
    return SD_disk_initialize(pdrv);
  /* USER CODE END INIT */
}

/**
  * @brief  Gets Disk Status 
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_status (
    BYTE pdrv       /* Physical drive number to identify the drive */
)
{
  /* USER CODE BEGIN STATUS */
    return SD_disk_status(pdrv);
  /* USER CODE END STATUS */
}

/**
  * @brief  Reads Sector(s) 
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data buffer to store read data
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to read (1..128)
  * @retval DRESULT: Operation result
  */
DRESULT USER_read (
    BYTE pdrv,      /* Physical drive nmuber to identify the drive */
    BYTE *buff,     /* Data buffer to store read data */
    DWORD sector,   /* Sector address in LBA */
    UINT count      /* Number of sectors to read */
)
{
  /* USER CODE BEGIN READ */
    return SD_disk_read(pdrv, buff, sector, count);
  /* USER CODE END READ */
}

/**
  * @brief  Writes Sector(s)  
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data to be written
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to write (1..128)
  * @retval DRESULT: Operation result
  */
#if _USE_WRITE == 1
DRESULT USER_write (
    BYTE pdrv,          /* Physical drive nmuber to identify the drive */
    const BYTE *buff,   /* Data to be written */
    DWORD sector,       /* Sector address in LBA */
    UINT count          /* Number of sectors to write */
)
{ 
  /* USER CODE BEGIN WRITE */
  /* USER CODE HERE */
    return SD_disk_write(pdrv, buff, sector, count);
  /* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */

/**
  * @brief  I/O control operation  
  * @param  pdrv: Physical drive number (0..)
  * @param  cmd: Control code
  * @param  *buff: Buffer to send/receive control data
  * @retval DRESULT: Operation result
  */
#if _USE_IOCTL == 1
DRESULT USER_ioctl (
    BYTE pdrv,      /* Physical drive nmuber (0..) */
    BYTE cmd,       /* Control code */
    void *buff      /* Buffer to send/receive control data */
)
{
  /* USER CODE BEGIN IOCTL */
    return SD_disk_ioctl(pdrv, cmd, buff);
  /* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */
#包括
#包括“ff_gen_drv.h”
#包括“FATF_sd.h”
/*私有类型定义-----------------------------------------------------------*/
/*私有定义------------------------------------------------------------*/
/*私有变量---------------------------------------------------------*/
/*磁盘状态*/
静态易失性数据状态Stat=Stat_NOINIT;
/*用户代码结束DECL*/
/*私有函数原型-----------------------------------------------*/
数据状态用户_初始化(字节pdrv);
数据状态用户_状态(字节pdrv);
DRESULT USER_read(字节pdrv、字节*buff、DWORD扇区、UINT计数);
#如果_使用_WRITE==1
数据结果用户写入(字节pdrv、常量字节*buff、DWORD扇区、UINT计数);
#endif/*\u USE\u WRITE==1*/
#如果使用IOCTL==1
DRESULT USER_ioctl(字节pdrv、字节cmd、void*buff);
#endif/*\u USE\u IOCTL==1*/
Diskio_drvTypeDef用户_驱动程序=
{
用户_初始化,
用户状态,
用户阅读,
#如果你用写
用户写入,
#endif/*\u USE\u WRITE==1*/
#如果使用IOCTL==1
用户ioctl,
#endif/*\u USE\u IOCTL==1*/
};
/*私人职能---------------------------------------------------------*/
/**
*@brief初始化驱动器
*@param pdrv:物理驱动器号(0..)
*@retval DSTATUS:操作状态
*/
数据状态用户初始化(
字节pdrv/*物理驱动器nmuber,用于标识驱动器*/
)
{
/*用户代码开始初始化*/
返回SD_磁盘_初始化(pdrv);
/*用户代码结束初始化*/
}
/**
*@brief获取磁盘状态
*@param pdrv:物理驱动器号(0..)
*@retval DSTATUS:操作状态
*/
数据状态用户状态(
字节pdrv/*用于标识驱动器的物理驱动器号*/
)
{
/*用户代码开始状态*/
返回SD_磁盘_状态(pdrv);
/*用户代码结束状态*/
}
/**
*@brief读取扇区(s)
*@param pdrv:物理驱动器号(0..)
*@param*buff:用于存储读取数据的数据缓冲区
*@param扇区:扇区地址(LBA)
*@param count:要读取的扇区数(1..128)
*@retval-DRESULT:操作结果
*/
DRESULT用户读取(
字节pdrv,/*物理驱动器nmuber以识别驱动器*/
字节*buff,/*数据缓冲区用于存储读取数据*/
DWORD扇区,/*LBA中的扇区地址*/
UINT count/*要读取的扇区数*/
)
{
/*用户代码开始读取*/
返回SD_磁盘_读取(pdrv、buff、扇区、计数);
/*用户代码结束读取*/
}
/**
*@brief写入扇区(s)
*@param pdrv:物理驱动器号(0..)
*@param*buff:要写入的数据
*@param扇区:扇区地址(LBA)
*@param count:要写入的扇区数(1..128)
*@retval-DRESULT:操作结果
*/
#如果_使用_WRITE==1
数据结果用户写入(
字节pdrv,/*物理驱动器nmuber以识别驱动器*/
常量字节*buff,/*要写入的数据*/
DWORD扇区,/*LBA中的扇区地址*/
UINT count/*要写入的扇区数*/
)
{ 
/*用户代码开始写入*/
/*这里的用户代码*/
返回SD_磁盘_写入(pdrv、buff、扇区、计数);
/*用户代码结束写入*/
}
#endif/*\u USE\u WRITE==1*/
/**
*@简短的I/O控制操作
*@param pdrv:物理驱动器号(0..)
*@param cmd:控制代码
*@param*buff:发送/接收控制数据的缓冲区
*@retval-DRESULT:操作结果
*/
#如果使用IOCTL==1
DRESULT用户\u ioctl(
字节pdrv,/*物理驱动器nmuber(0..)*/
字节cmd,/*控制代码*/
void*buff/*用于发送/接收控制数据的缓冲区*/
)
{
/*用户代码beginioctl*/
返回SD_disk_ioctl(pdrv、cmd、buff);
/*用户代码结束IOCTL*/
}
#endif/*\u USE\u IOCTL==1*/
而fatfs_sd.c看起来是这样的:

#include <string.h>
#include "ff_gen_drv.h"
#include "fatfs_sd.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;

/* USER CODE END DECL */

/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize (BYTE pdrv);
DSTATUS USER_status (BYTE pdrv);
DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
  DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);  
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
  DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
#endif /* _USE_IOCTL == 1 */

Diskio_drvTypeDef  USER_Driver =
{
  USER_initialize,
  USER_status,
  USER_read, 
#if  _USE_WRITE
  USER_write,
#endif  /* _USE_WRITE == 1 */  
#if  _USE_IOCTL == 1
  USER_ioctl,
#endif /* _USE_IOCTL == 1 */
};

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Initializes a Drive
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_initialize (
    BYTE pdrv           /* Physical drive nmuber to identify the drive */
)
{
  /* USER CODE BEGIN INIT */
    return SD_disk_initialize(pdrv);
  /* USER CODE END INIT */
}

/**
  * @brief  Gets Disk Status 
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_status (
    BYTE pdrv       /* Physical drive number to identify the drive */
)
{
  /* USER CODE BEGIN STATUS */
    return SD_disk_status(pdrv);
  /* USER CODE END STATUS */
}

/**
  * @brief  Reads Sector(s) 
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data buffer to store read data
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to read (1..128)
  * @retval DRESULT: Operation result
  */
DRESULT USER_read (
    BYTE pdrv,      /* Physical drive nmuber to identify the drive */
    BYTE *buff,     /* Data buffer to store read data */
    DWORD sector,   /* Sector address in LBA */
    UINT count      /* Number of sectors to read */
)
{
  /* USER CODE BEGIN READ */
    return SD_disk_read(pdrv, buff, sector, count);
  /* USER CODE END READ */
}

/**
  * @brief  Writes Sector(s)  
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data to be written
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to write (1..128)
  * @retval DRESULT: Operation result
  */
#if _USE_WRITE == 1
DRESULT USER_write (
    BYTE pdrv,          /* Physical drive nmuber to identify the drive */
    const BYTE *buff,   /* Data to be written */
    DWORD sector,       /* Sector address in LBA */
    UINT count          /* Number of sectors to write */
)
{ 
  /* USER CODE BEGIN WRITE */
  /* USER CODE HERE */
    return SD_disk_write(pdrv, buff, sector, count);
  /* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */

/**
  * @brief  I/O control operation  
  * @param  pdrv: Physical drive number (0..)
  * @param  cmd: Control code
  * @param  *buff: Buffer to send/receive control data
  * @retval DRESULT: Operation result
  */
#if _USE_IOCTL == 1
DRESULT USER_ioctl (
    BYTE pdrv,      /* Physical drive nmuber (0..) */
    BYTE cmd,       /* Control code */
    void *buff      /* Buffer to send/receive control data */
)
{
  /* USER CODE BEGIN IOCTL */
    return SD_disk_ioctl(pdrv, cmd, buff);
  /* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */
转到上面的GITHUB链接

我不知道我哪里出错了

关于这个话题的任何东西都会有帮助


提前谢谢

我以前为FATF使用stm32f7芯片编写过自己的驱动程序,我想我可能知道发生了什么。我的猜测是,您可能忘记为
diskio.h
中的
disk\u write
disk\u read
函数附加实现。如果不这样做,FatFS库就不知道如何实际与SD卡接口

您可以查阅FatFS文档/手册作为一般资源:

请密切关注本应用程序中的“必需功能”部分注意:


像您这样的示例项目,但对于STM32F4:

我认为您已经差不多做到了。我搜索了上面链接的源代码,找到了我前面提到的那些函数的所有存根定义。乍一看,它们看起来还不错。我找不到的是你在哪里把你的功能附加到FatFS驱动程序上。这是通过调用“FATFS_LinkDriver(const Diskio_drvTypeDef*drv,char*path)”完成的。在user_Diskio.c的第89行有Diskio_drvTypeDef结构的定义,并且似乎已经填写了函数句柄。现在你只需要通过调用那个link函数来让fatffatfs知道它存在,通过调用那个link函数来调用那个link函数,现在你只需要通过调用那个link函数来让FatFS知道它存在。我猜这是调用这个函数的调用
void>void MX>void MX\ufatfs\FatFS的FatFS(void)initinit(void){/*353555;##35日日日如果如果如果如果如果根据根据根据根据根据35日日日日日日日日日355日日日日日日日日\35支付支付支付支付支付支付支付的根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据根据本本本周五周五日日日日日日举行的35日日日日日日日日日日日日日日日日日日日日日日日据据据据据据据据##*/retUSER=FatFS_LinkDriver(&USER_driver,USERPath);/*用户代码BEGIN Init*//*其他用户代码用于Init*/*用户代码END Init*/}这个函数是从main调用的。嗯,是的,我看我错过了。我的错。除了开始,我不知道该告诉你什么