这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32F103ZET6】04:STM32cubeMX实现文件系统操作

共1条 1/1 1 跳转至

【STM32F103ZET6】04:STM32cubeMX实现文件系统操作

高工
2025-09-02 14:19:50     打赏

一:文件系统的知识分享:

FATFS 是一个完全免费开源的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C 语言编写,所以具有良好的硬件平台独立性,

可以移植到 8051、PIC、AVR、SH、Z80、H8、ARM 等系列单片机上而只需做简单的修改。它支持 FATI2、FATI6 和 FAT32,

支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和 16 位单片机做了优化。

FATFS 的特点有:

Windows 兼容的 FAT 文件系统(支持 FAT12/FAT16/FAT32)

与平台无关,移植简单

代码量少、效率高

多种配置选项

支持多卷(物理驱动器或分区,最多10个卷)

多个 ANSIOEM 代码页包括 DBCS

支持长文件名、ANSI/OEM 或 Unicode

支持 RTOS

支持多种扇区大小

只读、最小化的 API和 IO 缓冲区等

最顶层是应用层,使用者无需理会FATFS 的内部结构和复杂的 FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如fopen,f read,f write 和f close 等,就可以像在 PC 上读/写文件那样简单。

中间层 FATFS 模块,实现了 FAT 文件读/写协议。FATFS 模块提供的是 c 和 fh。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。

二:STM32 cube MX软件配置如下所示:

2.1 修改程序的堆栈大小

2.2 使能软件的文件系统的底层驱动部分

配置如上图所示,直接生成代码即可。

三:软件代码编写:

3.1  对于存储芯片的选择:

/**
  * @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 */
    Stat = STA_NOINIT;

  switch (pdrv)
  {
  case 1: // SD
    Stat = RES_PARERR;
    break;
  case 0: // flash
    Stat = RES_OK;
    break;
  default:
    Stat = RES_PARERR;
  }
  return Stat;
  /* USER CODE END INIT */
}

3.2  添加 写入文件的操作:

/**
  * @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 */
  if (pdrv == 0)
  {
	  W25QXX_Read((uint8_t *)buff ,sector * 4096, count * 4096);
    return RES_OK;
  }
  else
  {
    return RES_PARERR;
  }
  /* USER CODE END READ */
}

3.3 添加读取文件的操作:

#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 */
  if (pdrv == 0)
  {
    W25QXX_Erase_Sector(sector );
		W25QXX_Write_NoCheck((uint8_t *)buff,sector * 4096,  count * 4096);
    return RES_OK;
  }
  else
  {
    return RES_PARERR;
  }
  /* USER CODE END WRITE */
}

四:测试读取的函数如下所示:

这里我创建一个 以EEPW为名字的txt文件:

void FATFS_FLASH_Test(void)
{
  static FATFS fs;                    //文件系统对象
  static FIL fnew;                   //文件对象
  BYTE FATFS_Wr_Buff[128] = "hi.WWW.EEPW.COM.CN!   autor:by :keyboard !!!!!\r\n"; // 写缓冲区
  BYTE FATFS_Rd_Buff[128] = {0};                                         // 读缓冲区
  UINT fnum;                                                             // 成功读写数量
  FRESULT res;                                                           // 返回

  printf("\r\n\r\n------------------FLASH FATFS TEST------------------\r\n\r\n");
  res = f_mount(&fs, "0:", 1);
  if (res == FR_NO_FILESYSTEM)
  {
    printf("no file system,begin mkfs\r\n");
    res = f_mkfs("0:", 0, 0); //格式化 SPI的W25Q64
    if (res == FR_OK)
    {
      printf("file system mkfs ok\r\n");
      // 格式化成功后先取消,再重新挂载
      res = f_mount(NULL, "0:", 1);
      printf("cancel mount ok:%d\r\n", res);
      res = f_mount(&fs, "0:", 1);
      printf("re-mount ok:%d\r\n", res);
    }
    else
    {
      printf("failed mount\r\n");
    }
  }
  else
  {
    printf("file system alreadly existed.\r\n");
  }


  printf("\r\n\r\n-------------------FATFS write test-------------------\r\n");
  // 打开文件,文件不存在的话,则先新建文件在打开
  res = f_open(&fnew, "EEPW.txt", FA_CREATE_ALWAYS | FA_WRITE);
  if (res == FR_OK)
    printf("open or create EEPW.txt ok.\r\n");
  else
    printf("open or create file failed\r\n");
  // 写入测试buffer 到文件系统内
  res = f_write(&fnew, FATFS_Wr_Buff, sizeof(FATFS_Wr_Buff), &fnum);

  if (res == FR_OK)
    printf("write to EEPW.txt:\r\n%s", FATFS_Wr_Buff);
  else
    printf("failed to write EEPW.txt,code: %d!\r\n", res);

		f_close(&fnew); // 完成操作后,需要关闭文件,这一操作很重要
	 HAL_Delay(200);
  

  printf("\r\n-------------------FATFS read test-------------------\r\n\r\n");
  // 打开文件,读方式打开已经创建的文件
  res = f_open(&fnew, "EEPW.txt", FA_OPEN_EXISTING | FA_READ);
  if (res != FR_OK)
  {
    printf("open EEPW.txt failed\r\n");
    return;
  }
  //读取文件测试
  res = f_read(&fnew, FATFS_Rd_Buff, sizeof(FATFS_Rd_Buff), &fnum);
  if (res != FR_OK)
  {
    printf("read file failed\r\n");
    return;
  }
  printf("read file data:\r\n%s\r\n", FATFS_Rd_Buff);

  f_close(&fnew); // 读取完毕后,也需要关闭文件
}

五:测试图如下所示:

04-3.png

实测软件代码功能正常,可以正常使用文件系统的格式写入和读取文件。




关键词: STM32F103ZET6     文件系统    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]