在STM32中移植FATFS文件资料系统

上传人:痛*** 文档编号:91690487 上传时间:2022-05-17 格式:DOC 页数:16 大小:597.50KB
返回 下载 相关 举报
在STM32中移植FATFS文件资料系统_第1页
第1页 / 共16页
在STM32中移植FATFS文件资料系统_第2页
第2页 / 共16页
在STM32中移植FATFS文件资料系统_第3页
第3页 / 共16页
点击查看更多>>
资源描述
wordSTM32的FATFS文件系统移植笔记一、序言 经常在网上、群里看到很多人问关于STM32的FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。二、FATFS简介 FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进展读写,并特别对8位单片机和16位单片机做了优化。三、移植准备 1、FATFS源代码的获取,可以到官网下载:最新版本是版本,我们就移植这个版本的。 2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。另一个是src文件夹,里面就是我们所要的源文件。 3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。可以参考已经建立好的printf()打印输出工程:四、开始移植 1、在已经建立好的工程目录User文件夹下新建两个文件夹,和SPI_SD_Card,用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。 2、如图1将添加到工程文件夹中,并新建文件,在文件中实现五个函数:1. DSTATUS disk_initialize (BYTE);/SD卡的初始化2. DSTATUS disk_status (BYTE);/获取SD卡的状态,这里可以不用管3. DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);/从SD卡读取数据4. DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);/将数据写入SD卡,假如该文件系统为只读文件系统如此不用实现该函数5. DRESULT disk_ioctl (BYTE, BYTE, void*);/获取SD卡文件系统相关信息6.复制代码图1 3、初步实现以上五个函数 FATFS初始化函数:1. DSTATUS disk_initialize (2. BYTE drv /* Physical drive nmuber (0.) */3. )4. 5. switch (drv)6. 7. case 0 :8. return RES_OK;9. case 1 :10. return RES_OK; 11. case 2 :12. return RES_OK; 13. case 3 :14. return RES_OK;15. default:16. return STA_NOINIT;17. 18. 复制代码FATFS状态获取函数:1. DSTATUS disk_status (2. BYTE drv /* Physical drive nmuber (0.) */3. )4. 5. switch (drv)6. 7. case 0 :8. return RES_OK;9. case 1 :10. return RES_OK;11. case 2 :12. return RES_OK;13. default:14. return STA_NOINIT;15. 16. 复制代码FATFS底层读数据函数:1. DRESULT disk_read (2. BYTE drv, /* Physical drive nmuber (0.) */3. BYTE *buff, /* Data buffer to store read data */4. DWORD sector, /* Sector address (LBA) */5. BYTE count /* Number of sectors to read (1.255) */6. )7. 8. if( !count )9. 10. return RES_PARERR;/* count不能等于0,否如此返回参数错误 */11. 12. switch (drv)13. 14. case 0:15. if(count=1) /* 1个sector的读操作 */ 16. 17. return RES_OK; 18. 19. else /* 多个sector的读操作 */ 20. 21. return RES_OK;22. 23. case 1:24. if(count=1) /* 1个sector的读操作 */ 25. 26. return RES_OK; 27. 28. else /* 多个sector的读操作 */ 29. 30. return RES_OK;31. 32.33. default:34. return RES_ERROR;35. 36. 复制代码FATFS底层写数据函数:1. DRESULT disk_write (2. BYTE drv, /* Physical drive nmuber (0.) */3. const BYTE *buff, /* Data to be written */4. DWORD sector, /* Sector address (LBA) */5. BYTE count /* Number of sectors to write (1.255) */6. )7. 8. if( !count )9. 10. return RES_PARERR;/* count不能等于0,否如此返回参数错误 */11. 12. switch (drv)13. 14. case 0:15. if(count=1) /* 1个sector的写操作 */ 16. 17. return RES_OK;18. 19. else /* 多个sector的写操作 */ 20. 21. return RES_OK;22. 23. case 1:24. if(count=1) /* 1个sector的写操作 */ 25. 26. return RES_OK;27. 28. else /* 多个sector的写操作 */ 29. 30. return RES_OK;31. 32. 33. default:return RES_ERROR;34. 35. 复制代码FATFS磁盘控制函数:1. DRESULT disk_ioctl (2. BYTE drv, /* Physical drive nmuber (0.) */3. BYTE ctrl, /* Control code */4. void *buff /* Buffer to send/receive control data */5. )6. 7. if (drv=0)8. 9. switch (ctrl)10. 11. case CTRL_SYNC :12. return RES_OK;13. case GET_SECTOR_COUNT :14. return RES_OK;15. case GET_BLOCK_SIZE :16. return RES_OK; 17. case CTRL_POWER :18. break;19. case CTRL_LOCK :20. break;21. case CTRL_EJECT :22. break;23. /* MMC/SDC mand */24. case MMC_GET_TYPE :25. break;26. case MMC_GET_CSD :27. break;28. case MMC_GET_CID :29. break;30. case MMC_GET_OCR :31. break;32. case MMC_GET_SDSTAT :33. break; 34. 35. else if(drv=1)36. switch (ctrl)37. 38. case CTRL_SYNC :39. return RES_OK;40. case GET_SECTOR_COUNT :41. return RES_OK;42. case GET_SECTOR_SIZE :43. return RES_OK;44. case GET_BLOCK_SIZE :45. return RES_OK; 46. case CTRL_POWER :47. break;48. case CTRL_LOCK :49. break;50. case CTRL_EJECT :51. break;52. /* MMC/SDC mand */53. case MMC_GET_TYPE :54. break;55. case MMC_GET_CSD :56. break;57. case MMC_GET_CID :58. break;59. case MMC_GET_OCR :60. break;61. case MMC_GET_SDSTAT :62. break; 63. 64. 65. else 66. return RES_PARERR;67. 68. return RES_PARERR;69. 复制代码以上函数都只是实现一个框架,并没有做实际的事情,下一步就需要把操作SD卡的程序填充在这个框架里面。 4、实现disk_initialize()函数 该函数在挂载文件系统的时候会被调用,主要是实现读写SD卡前对SD卡进展初始化,根据SD卡的传输协议,我们按照如下步骤初始化SD卡: a、判断SD卡是否插入,可以通过检查SD卡卡座的CD脚电平进展判断,一般插入卡后该引脚会变成低电平。 b、稍微延时一段时间后发送至少74个时钟给SD卡。 c、发送CMD0命令给SD卡,直到SD卡返回0x01为止,这里可以循环屡次发送。 程序如下:1. /* Start send CMD0 till return 0x01 means in IDLE state */2. for(retry=0; retry0xFFF; retry+)3. 4. r1 = MSD0_send_mand(CMD0, 0, 0x95);5. if(r1 = 0x01)6. 7. retry = 0;8. break;9. 10. 复制代码d、发送CMD8获取卡的类型,不同类型的卡其初始化方式有所不同。 e、根据卡的类型对卡进展初始化。具体初始化方式可以参考附件程序。 注:在初始化SD卡之前应该初始化SPI接口和相关的管脚。 实现后的程序如下:1. DSTATUS disk_initialize (2. BYTE drv /* Physical drive nmuber (0.) */3. )4. 5. int Status;6. switch (drv)7. 8. case 0 :9. Status = MSD0_Init();10. if(Status=0)11. return RES_OK;12. else13. return STA_NOINIT;14. 15. case 1 :16. return RES_OK; 17. case 2 :18. return RES_OK; 19. case 3 :20. return RES_OK;21. default:22. return STA_NOINIT;23. 24. 复制代码MSD0_Init()函数在文件中实现。 5、实现disk_read()函数 该函数是读取SD卡扇区数据的函数,根据SD卡数据传输协议可知有读取单扇区和读取多扇区两种操作模式,为提高读文件的速度应该实现读取多扇区函数。 实现后的程序如下:1. DRESULT disk_read (2. BYTE drv, /* Physical drive nmuber (0.) */3. BYTE *buff, /* Data buffer to store read data */4. DWORD sector, /* Sector address (LBA) */5. BYTE count /* Number of sectors to read (1.255) */6. )7. 8. int Status;9. if( !count )10. 11. return RES_PARERR;/* count不能等于0,否如此返回参数错误 */12. 13. switch (drv)14. 15. case 0:16. if(count=1) /* 1个sector的读操作 */ 17. 18. Status=MSD0_ReadSingleBlock( sector ,buff );19. if(Status = 0)20. return RES_OK;21. else22. return RES_ERROR;23. 24. 25. else /* 多个sector的读操作 */ 26. 27. Status = MSD0_ReadMultiBlock( sector , buff ,count);28. if(Status = 0)29. return RES_OK;30. else31. return RES_ERROR;32. 33. 34. case 1:35. if(count=1) /* 1个sector的读操作 */ 36. 37. return RES_OK; 38. 39. else /* 多个sector的读操作 */ 40. 41. return RES_OK;42. 43.44. default:45. return RES_ERROR;46. 47. MSD0_ReadSingleBlock()和MSD0_ReadMultiBlock()函数都是SD卡操作的底层函数,我们在文件中实现。 6、实现disk_write()函数 该函数主要实现对SD卡进展写数据操作,和读数据操作一样也分单块写和多块写,建议实现多块写的方式,这样可以提高写数据速度。 实现后的程序如下:1. DRESULT disk_write (2. BYTE drv, /* Physical drive nmuber (0.) */3. const BYTE *buff, /* Data to be written */4. DWORD sector, /* Sector address (LBA) */5. BYTE count /* Number of sectors to write (1.255) */6. )7. 8. int Status;9. if( !count )10. 11. return RES_PARERR;/* count不能等于0,否如此返回参数错误 */12. 13. switch (drv)14. 15. case 0:16. if(count=1) /* 1个sector的写操作 */ 17. 18. Status = MSD0_WriteSingleBlock( sector , (uint8_t *)(&buff0) );19. if(Status = 0)20. return RES_OK;21. else22. return RES_ERROR;23. 24. 25. else /* 多个sector的写操作 */ 26. 27. Status = MSD0_WriteMultiBlock( sector , (uint8_t *)(&buff0) , count );28. if(Status = 0)29. return RES_OK;30. else31. return RES_ERROR;32. 33. 34. case 1:35. if(count=1) /* 1个sector的写操作 */ 36. 37. return RES_OK;38. 39. else /* 多个sector的写操作 */ 40. 41. return RES_OK;42. 43. 44. default:return RES_ERROR;45. 46. MSD0_WriteSingleBlock()和MSD0_WriteMultiBlock()函数都是SD卡操作的底层函数,我们在文件中实现。 7、实现disk_ioctl()函数 该函数在磁盘格式化、获取文件系统信息等操作时会被调用。 实现后的程序如下:1. DRESULT disk_ioctl (2. BYTE drv, /* Physical drive nmuber (0.) */3. BYTE ctrl, /* Control code */4. void *buff /* Buffer to send/receive control data */5. )6. 7. if (drv=0)8. 9. MSD0_GetCardInfo(&SD0_CardInfo);10. switch (ctrl)11. 12. case CTRL_SYNC :13. return RES_OK;14. case GET_SECTOR_COUNT :15. *(DWORD*)buff = SD0_CardInfo.Capacity/SD0_CardInfo.BlockSize;16. return RES_OK;17. case GET_BLOCK_SIZE :18. *(WORD*)buff = SD0_CardInfo.BlockSize;19. return RES_OK; 20. case CTRL_POWER :21. break;22. case CTRL_LOCK :23. break;24. case CTRL_EJECT :25. break;26. /* MMC/SDC mand */27. case MMC_GET_TYPE :28. break;29. case MMC_GET_CSD :30. break;31. case MMC_GET_CID :32. break;33. case MMC_GET_OCR :34. break;35. case MMC_GET_SDSTAT :36. break; 37. 38. else if(drv=1)39. switch (ctrl)40. 41. case CTRL_SYNC :42. return RES_OK;43. case GET_SECTOR_COUNT :44. return RES_OK;45. case GET_SECTOR_SIZE :46. return RES_OK;47. case GET_BLOCK_SIZE :48. return RES_OK; 49. case CTRL_POWER :50. break;51. case CTRL_LOCK :52. break;53. case CTRL_EJECT :54. break;55. /* MMC/SDC mand */56. case MMC_GET_TYPE :57. break;58. case MMC_GET_CSD :59. break;60. case MMC_GET_CID :61.
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!