[单片机芯片] 【CH32F207VCT6】开发例程+10基于W25Q64实现文件系统

[复制链接]
508|0
聪聪哥哥 发表于 2025-9-29 20:41 | 显示全部楼层 |阅读模式
开发, , , , VC, CH32F207
本帖最后由 聪聪哥哥 于 2025-9-29 20:46 编辑

一:文件系统的知识分享:
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。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
二:软件代码的移植:
在之前的章节中,我们已经完成对SPI通讯的W25Q64的驱动,在此基础上我尝试使用文件系统的操作对文件进行管理。
2.1 在文件系统的代码中,添加对存储芯片SPI。或者试SD卡的配置如下所示:
  1. DSTATUS USER_initialize (
  2.         BYTE pdrv           /* Physical drive nmuber to identify the drive */
  3. )
  4. {
  5.   /* USER CODE BEGIN INIT */
  6.     Stat = STA_NOINIT;

  7.   switch (pdrv)
  8.   {
  9.   case 1: // SD
  10.     Stat = RES_PARERR;
  11.     break;
  12.   case 0: // flash
  13.     Stat = RES_OK;
  14.     break;
  15.   default:
  16.     Stat = RES_PARERR;
  17.   }
  18.   return Stat;
  19.   /* USER CODE END INIT */
  20. }
2.2 在文件系统的文件中添加对写入数据操作如下所示:
  1. DRESULT USER_write (
  2.         BYTE pdrv,          /* Physical drive nmuber to identify the drive */
  3.         const BYTE *buff,   /* Data to be written */
  4.         DWORD sector,       /* Sector address in LBA */
  5.         UINT count          /* Number of sectors to write */
  6. )
  7. {
  8.   /* USER CODE BEGIN WRITE */
  9.   /* USER CODE HERE */
  10.   if (pdrv == 0)
  11.   {
  12. //   W25QXX_Erase_Sector(sector );
  13. //                W25QXX_Write_NoCheck((uint8_t *)buff,sector * 4096,  count * 4096);
  14.     SPI_Flash_Erase_Sector(sector );
  15.                 SPI_Flash_Write((uint8_t *)buff,sector * 4096,  count * 4096);
  16.     return RES_OK;
  17.   }
  18.   else
  19.   {
  20.     return RES_PARERR;
  21.   }
  22.   /* USER CODE END WRITE */
  23. }
2.3 添加读取文件的操作:
  1. DRESULT USER_read (
  2.         BYTE pdrv,      /* Physical drive nmuber to identify the drive */
  3.         BYTE *buff,     /* Data buffer to store read data */
  4.         DWORD sector,   /* Sector address in LBA */
  5.         UINT count      /* Number of sectors to read */
  6. )
  7. {
  8.   /* USER CODE BEGIN READ */
  9.   if (pdrv == 0)
  10.   {
  11.           //W25QXX_Read((uint8_t *)buff ,sector * 4096, count * 4096);
  12.                 SPI_Flash_Read( (uint8_t *) buff, sector * 4096, count * 4096 );
  13.     return RES_OK;
  14.   }
  15.   else
  16.   {
  17.     return RES_PARERR;
  18.   }
  19.   /* USER CODE END READ */
  20. }
三:测试读写程序如下所示:
  1. void FATFS_FLASH_Test(void)
  2. {
  3.   static FATFS fs;                    //文件系统对象
  4.   static FIL fnew;                   //文件对象
  5.   BYTE FATFS_Wr_Buff[128] = "hi.WWW.21IC.COM.CN!   autor:by :congconggege !!!!!\r\n"; // 写缓冲区
  6.   BYTE FATFS_Rd_Buff[128] = {0};                                         // 读缓冲区
  7.   UINT fnum;                                                             // 成功读写数量
  8.   FRESULT res;                                                           // 返回

  9.   printf("\r\n\r\n------------------FLASH FATFS TEST------------------\r\n\r\n");
  10.   res = f_mount(&fs, "0:", 1);
  11.   if (res == FR_NO_FILESYSTEM)
  12.   {
  13.     printf("no file system,begin mkfs\r\n");
  14.     res = f_mkfs("0:", 0, 0); //格式化 SPI的W25Q64
  15.     if (res == FR_OK)
  16.     {
  17.       printf("file system mkfs ok\r\n");
  18.       // 格式化成功后先取消,再重新挂载
  19.       res = f_mount(NULL, "0:", 1);
  20.       printf("cancel mount ok:%d\r\n", res);
  21.       res = f_mount(&fs, "0:", 1);
  22.       printf("re-mount ok:%d\r\n", res);
  23.     }
  24.     else
  25.     {
  26.       printf("failed mount\r\n");
  27.     }
  28.   }
  29.   else
  30.   {
  31.     printf("file system alreadly existed.\r\n");
  32.   }


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

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

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

  49.   printf("\r\n-------------------FATFS read test-------------------\r\n\r\n");
  50.   // 打开文件,读方式打开已经创建的文件
  51.   res = f_open(&fnew, "CH32F207.txt", FA_OPEN_EXISTING | FA_READ);
  52.   if (res != FR_OK)
  53.   {
  54.     printf("open CH32F207.txt failed\r\n");
  55.     return;
  56.   }
  57.   //读取文件测试
  58.   res = f_read(&fnew, FATFS_Rd_Buff, sizeof(FATFS_Rd_Buff), &fnum);
  59.   if (res != FR_OK)
  60.   {
  61.     printf("read file failed\r\n");
  62.     return;
  63.   }
  64.   printf("read file data:\r\n%s\r\n", FATFS_Rd_Buff);

  65.   f_close(&fnew); // 读取完毕后,也需要关闭文件
  66. }
四:使用串口工具实测一下,程序执行的过程:
10-2.png
10-3.png
10-1.png
实测:软件代码功能正常,可以正常使用文件系统的格式写入和读取文件。等等对代码的格式进行整理,和大家分享一下,具体的实现过程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

108

主题

307

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部