[开发工具] STM32CubeMX-22 | 在SD卡上移植FATFS文件系统

[复制链接]
2685|48
 楼主| manufact 发表于 2020-4-13 16:00 | 显示全部楼层
然后直接右键选择格式化:
536075e941bf93ff65.png
 楼主| manufact 发表于 2020-4-13 16:00 | 显示全部楼层
如果第二种方法没用的话,可以使用第三种方法,来打开 DiskGenius 软件查看SD卡:

8395e941c1862c25.png
 楼主| manufact 发表于 2020-4-13 16:01 | 显示全部楼层
重新建立分区表并格式化:

231455e941c39a59c2.png
675795e941c412acc6.png
926365e941c481b20c.png
 楼主| manufact 发表于 2020-4-13 16:01 | 显示全部楼层
之后可以看到SD卡恢复正常,可以进行FATFS实验啦:
840375e941c5b13874.png
 楼主| manufact 发表于 2020-4-13 16:02 | 显示全部楼层
使用FATFS挂载SD卡
      注意:在挂载之前必须要保证SD卡正常拥有FAT文件系统。

挂载文件系统使用f_mount API,该API将文件系统对象注册/注销到FatFs模块,API原型如下:

  1. FRESULT f_mount (
  2.   FATFS*       fs,    /* [IN] Filesystem object */
  3.   const TCHAR* path,  /* [IN] Logical drive number */
  4.   BYTE         opt    /* [IN] Initialization option */
  5. );
 楼主| manufact 发表于 2020-4-13 16:02 | 显示全部楼层
在main.c文件中添加如下代码,先定义FATFS所使用的一些全局变量:

  1. /* Private variables ---------------------------------------------------------*/

  2. /* USER CODE BEGIN PV */
  3. FATFS   fs;            /* FATFS 文件系统对象 */
  4. FRESULT fr;         /* FATFS API 返回值 */
  5. /* USER CODE END PV */
 楼主| manufact 发表于 2020-4-13 16:03 | 显示全部楼层
然后在 main 函数中,while(1)之前添加如下代码:

  1. /* USER CODE BEGIN 2 */
  2. printf("FATFS test...\r\n");
  3. /* 挂载SD卡 */
  4. fr = f_mount(&fs, "", 0);
  5. if(fr == FR_OK)
  6. {
  7.     printf("SD card mount ok!\r\n");
  8. }
  9. else
  10. {
  11.     printf("SD card mount error, error code:%d.\r\n",fr);
  12. }
  13. /* USER CODE END 2 */
 楼主| manufact 发表于 2020-4-13 16:03 | 显示全部楼层
编译下载,运行结果如下:

221985e941ce09ec3e.png
 楼主| manufact 发表于 2020-4-13 16:04 | 显示全部楼层
创建文件并向文件中写入内容
要想操作文件,需要先创建文件对象:

  1. /* USER CODE BEGIN PV */
  2. FATFS   fs;            /* FATFS 文件系统对象 */
  3. FRESULT fr;         /* FATFS API 返回值 */
  4. FIL     fd;         /* FATFS 文件对象    */
  5. /* USER CODE END 2 */
 楼主| manufact 发表于 2020-4-13 16:05 | 显示全部楼层
在main函数中的开始定义要写入文件的内容:

  1. /* USER CODE BEGIN 1 */
  2. //要操作的文件名
  3. char filename[] = "test.txt";
  4. //文件写入内容
  5. uint8_t write_dat[] = "Hello,FATFS!\n";
  6. //用于接收API返回写入成功的字节数
  7. uint16_t write_num = 0;
  8. /* USER CODE END 1 */
 楼主| manufact 发表于 2020-4-13 16:05 | 显示全部楼层
然后在挂载操作成功之后进行打开->写入->关闭一个完整的操作:

  1. /* 打开文件(若文件不存在则创建) */
  2. fr = f_open(&fd, filename, FA_CREATE_ALWAYS | FA_WRITE);
  3. if(fr == FR_OK)
  4. {
  5.     printf("open file "%s" ok! \r\n", filename);
  6. }
  7. else
  8. {
  9. printf("open file "%s" error : %d\r\n", filename, fr);
  10. }

  11. /* 向打开的文件中写入内容 */
  12. fr = f_write(&fd, write_dat, sizeof(write_dat), (void *)&write_num);
  13. if(fr == FR_OK)
  14. {
  15.     printf("write %d dat to file "%s" ok,dat is "%s".\r\n", write_num, filename, write_dat);
  16. }
  17. else
  18. {
  19.     printf("write dat to file "%s" error,error code is:%d\r\n", filename, fr);
  20. }

  21. /* 操作完成,关闭文件 */
  22. fr = f_close(&fd);
  23. if(fr == FR_OK)
  24. {
  25.     printf("close file "%s" ok!\r\n", filename);
  26. }
  27. else
  28. {
  29.     printf("close file "%s" error, error code is:%d.\r\n", filename, fr);
  30. }
 楼主| manufact 发表于 2020-4-13 16:06 | 显示全部楼层
实验结果如下:

317005e941d667600e.png
 楼主| manufact 发表于 2020-4-13 16:06 | 显示全部楼层
再将SD卡插到电脑,可以看到文件及其内容:

190345e941d8aacccc.png
 楼主| manufact 发表于 2020-4-13 16:07 | 显示全部楼层
读取SD卡中的文件内容
同样的,先在main函数开始开辟一块缓冲区,用于存放读取的数据:

  1. /* USER CODE BEGIN 1 */
  2. //要操作的文件名
  3. char filename[] = "test.txt";
  4. //文件写入内容
  5. uint8_t write_dat[] = "Hello,FATFS!";
  6. //用于接收API返回写入成功的字节数
  7. uint16_t write_num = 0;

  8. //用于存放从文件中读取出的内容
  9. uint8_t read_dat[20];
  10. //用于接收API返回成功读取的字节数
  11. uint16_t read_num = 0;
  12. /* USER CODE END 1 */
 楼主| manufact 发表于 2020-4-13 16:07 | 显示全部楼层
然后进行打开->读取->关闭一个完整的操作:

  1. /* 打开文件用于读取 */
  2. fr = f_open(&fd, filename, FA_READ);
  3. if(fr == FR_OK)
  4. {
  5.     printf("open file "%s" ok! \r\n", filename);
  6. }
  7. else
  8. {
  9. printf("open file "%s" error : %d\r\n", filename, fr);
  10. }

  11. /* 从打开的文件中读取内容 */
  12. fr = f_read(&fd, read_dat, sizeof(read_dat), (void *)&read_num);
  13. if(fr == FR_OK)
  14. {
  15.     printf("read %d dat to file "%s" ok,dat is "%s".\r\n", read_num, filename, read_dat);
  16. }
  17. else
  18. {
  19.     printf("read dat to file "%s" error,error code is:%d\r\n", filename, fr);
  20. }

  21. /* 操作完成,关闭文件 */
  22. fr = f_close(&fd);
  23. if(fr == FR_OK)
  24. {
  25.     printf("close file "%s" ok!\r\n", filename);
  26. }
  27. else
  28. {
  29.     printf("close file "%s" error, error code is:%d.\r\n", filename, fr);
  30. }
 楼主| manufact 发表于 2020-4-13 16:08 | 显示全部楼层
实验现象如下:

918145e941dee292a8.png
 楼主| manufact 发表于 2020-4-13 16:09 | 显示全部楼层
FATFS API 错误码的使用
不知道大家有没有注意到,在本文中所有使用FATFS API的时候,都是如下的格式:

     使用FRESULT类型的变量fr接收API返回值
     API执行之后进行判断,错误的话输出错误码
 楼主| manufact 发表于 2020-4-13 16:09 | 显示全部楼层
那么,API 所返回的错误码,有什么用呢?下面用一个实例来给大家演示一下~

假如本文中的实验现象如下:

365265e941e34563fe.png
 楼主| manufact 发表于 2020-4-13 16:10 | 显示全部楼层
可以看到,FATFS创建文件时,返回的错误码是13,那么如何定位该问题呢?13代表什么?

打开FATFS的ff.h文件即可看到所有错误码所表示的含义:

681325e941e578d7b0.png
 楼主| manufact 发表于 2020-4-13 16:10 | 显示全部楼层
这样问题就定位到了,我们使用的SD卡是之前用于裸机实验的卡,SD卡分区被破坏,SD卡文件系统被破坏,所以FATFS创建文件时才会提示FR_NO_FILESYSTEM问题。

至此,我们已经学会如何在SD卡上移植​FATFS文件系统。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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