FATFS 成功应用于STM32F4的SPI FLASH!
最编程
2024-01-11 17:52:00
...
继上一篇博客https://www.cnblogs.com/showtime20190824/p/11523402.html
这一次我们我们再深入探讨了解一下FATFS的移植过程,并尝试在其他内存上进行拓展物理磁盘,博主成功移植于SPI FLASH,硬件为W25Q256,32MB。
关于外部FLASH,具体的细节就不说了,如果对其不是很了解,建议先去学习一下。这里主要提几点需要注意的:
首先,与上一篇博客的SD卡不同的是,该FLASH的扇区sector大小不是512字节,而是4096字节,每个block块有16个扇区,每个block大小为65536,因此在CUBEMX中需要调节一个参数(最大扇区大小)
其次,需要选一下FATFS下拉列表中的user-defined,接着生成工程文件
自己拓展用户自定义磁盘需要在user-diskio.c中添加API接口函数,这点与SD卡不同,因为SD卡自动帮你添加了这些接口,非常方便。
下一步,打开user-diskio.c,添加接口函数,具体有USER_read,USER_write,USER_ioctl三个部分
首先根据我们选择的硬件,添加几个宏定义:
#include "STW_w25qxx.h" #define FLASH_SECTOR_SIZE 4096 #define FLASH_SECTOR_COUNT 256*25 //W25Q256,Ç°25M×Ö½Ú¸øFATFSÕ¼Óà #define FLASH_BLOCK_SIZE 65536 //ÿ¸öBLOCKÓÐ8¸öÉÈÇø
接下来修改三个部分的API函数(函数原型框架已经搭好了,只需添加有色字体的代码):
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 */ for(;count>0;count--){ W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector++; buff+=FLASH_SECTOR_SIZE; } return RES_OK; /* USER CODE END READ */ }
#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 */ for(;count>0;count--){ W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector++; buff+=FLASH_SECTOR_SIZE; } return RES_OK; /* USER CODE END WRITE */ }
#endif /* _USE_WRITE == 1 */
#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 */ DRESULT res = RES_ERROR; switch(cmd){ case CTRL_SYNC: res = RES_OK; break; case GET_SECTOR_SIZE: *(WORD*)buff = FLASH_SECTOR_SIZE; res = RES_OK; break; case GET_BLOCK_SIZE: *(WORD*)buff = (WORD)FLASH_BLOCK_SIZE; res = RES_OK; break; case GET_SECTOR_COUNT: *(DWORD*)buff = FLASH_SECTOR_COUNT; res = RES_OK; break; default: res = RES_PARERR; break; } return res; /* USER CODE END IOCTL */ } #endif /* _USE_IOCTL == 1 */
OK,以上,我们完成了对外部FLASH的FATFS框架搭建,现在让我们编写相关代码实验一下:
void FATFS_MOUNT(void){ POINT_COLOR = DARKBLUE; LCD_ShowString(400,400,500,24,24,"****** FATFS START ******"); retSD = f_mount(&SDFatFS, "", 0) && f_mount(&USERFatFS, "", 0); if(retSD){ LCD_ShowString(400,440,500,24,24,"****** mount error ******"); LCD_ShowNum(800,440,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,440,500,24,24,"****** mount successfully!!! ******"); }
void FATFS_WRITE_TEST(void){ POINT_COLOR = DARKBLUE; retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE) && f_open(&USERFile, filename, FA_CREATE_ALWAYS | FA_WRITE);; if(retSD){ LCD_ShowString(400,480,500,24,24,"****** open file error ******"); LCD_ShowNum(800,480,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******"); retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten) && f_write(&USERFile, wtext, sizeof(wtext), (void *)&byteswritten); if(retSD){ LCD_ShowString(400,520,500,24,24,"****** write file error ******"); LCD_ShowNum(800,520,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,520,500,24,24,"****** write file successfully!!! ******"); retSD = f_close(&SDFile) && f_close(&USERFile); if(retSD){ LCD_ShowString(400,560,500,24,24,"****** close file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******"); }
void FAFTF_READ_FILE_TEST(void){ POINT_COLOR = DARKBLUE; retSD = f_open(&USERFile, filename, FA_READ);; if(retSD){ LCD_ShowString(400,480,500,24,24,"****** open file error ******"); LCD_ShowNum(800,480,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******"); retSD = f_read(&USERFile, rtext, sizeof(rtext), (void *)&bytesread); if(retSD){ LCD_ShowString(400,520,500,24,24,"****** read file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,520,500,24,24,"****** read file successfully!!! ******"); retSD = f_close(&USERFile); if(retSD){ LCD_ShowString(400,560,500,24,24,"****** close file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******"); POINT_COLOR = RED; LCD_ShowString(300,640,260,24,24,"The File Content is:"); LCD_ShowString(560,640,500,24,24,(char*)rtext); }
博主写了以上三个测试函数,在初始化之后while(1)之前加入下面代码:
FATFS_MOUNT();
FATFS_WRITE_TEST();
FAFTF_READ_FILE_TEST();
测试结果如下:
最后,提供工程文件下载链接。觉得有帮助的朋友可以关注一下博主。
链接:https://pan.baidu.com/s/1en7C-aezeWjK2dtSN20pnw
提取码:ibga