你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【HAL库每天一例】第047例: SPI-基于串行Flash的FatFS文件系统

[复制链接]
haohao663 发布时间:2016-6-21 10:11
【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:https://pan.baidu.com/s/1i574oPv
密码:r3s3
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-047. SPI-基于串行Flash的FatFS文件系统
/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-047. SPI-基于串行Flash的FatFS文件系统
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:www ing10bbs com
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
  串行Flash用于存储数据。YS-F1Pro开发板集成了一个16M字节的W25Q128串行Flash芯片,可以
用于存放数据。该芯片使用SPI1通信接口。
  FatFS是一个专门为嵌入式开发的开源小型文件系统。FatFS可以提供丰富的文件操作函数,方便
文件操作,我们可以在串行Flash空间上移植FatFS文件系统。

【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口(需要安装驱
动),在电脑端打开串口调试助手工具,设置参数为115200 8-N-1。下载完程序之后,在串口调试
助手窗口可接收到信息。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/


CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg



spiflash_diskio.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: spiflash_diskio.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: 串行FLASH与FatFS文件系统桥接函数实现
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include <string.h>
  19. #include "ff_gen_drv.h"
  20. #include "spiflash/bsp_spiflash.h"

  21. /* 私有类型定义 --------------------------------------------------------------*/
  22. /* 私有宏定义 ----------------------------------------------------------------*/
  23. #define SPI_FLASH_REBUILD           1    // 1:使能格式化串行Flash,0:禁用格式化串行Flash
  24. #define SPI_FLASH_SECTOR_SIZE    4096    // 串行Flash扇区大小
  25. #define SPI_FLASH_START_SECTOR   1792    // 串行Flash文件系统FatFS偏移量
  26. #define SPI_FLASH_SECTOR_COUNT   2304    // 串行Flash文件系统FatFS占用扇区个数   



  27. /* 私有变量 ------------------------------------------------------------------*/
  28. static __IO DSTATUS Stat = STA_NOINIT;

  29. /* 扩展变量 ------------------------------------------------------------------*/
  30. /* 私有函数原形 --------------------------------------------------------------*/
  31. DSTATUS SPIFLASH_initialize(BYTE);
  32. DSTATUS SPIFLASH_status(BYTE);
  33. DRESULT SPIFLASH_read(BYTE, BYTE*, DWORD, UINT);

  34. #if _USE_WRITE == 1   // 如果允许写操作
  35.   DRESULT SPIFLASH_write (BYTE, const BYTE*, DWORD, UINT);
  36. #endif /* _USE_WRITE == 1 */

  37. #if _USE_IOCTL == 1   // 如果输入输出操作控制
  38.   DRESULT SPIFLASH_ioctl (BYTE, BYTE, void*);
  39. #endif  /* _USE_IOCTL == 1 */

  40. /* 定义串行FLASH接口函数 */
  41. const Diskio_drvTypeDef  SPIFLASH_Driver =
  42. {
  43.   SPIFLASH_initialize,                   // 串行FLASH初始化
  44.   SPIFLASH_status,                       // 串行FLASH状态获取
  45.   SPIFLASH_read,                         // 串行FLASH读数据
  46. #if  _USE_WRITE == 1
  47.   SPIFLASH_write,                        // 串行FLASH写数据
  48. #endif /* _USE_WRITE == 1 */
  49.   
  50. #if  _USE_IOCTL == 1
  51.   SPIFLASH_ioctl,                         // 获取串行FLASH信息
  52. #endif /* _USE_IOCTL == 1 */
  53. };

  54. /* 函数体 --------------------------------------------------------------------*/
  55. /**
  56.   * 函数功能: 串行FLASH初始化配置
  57.   * 输入参数: 无
  58.   * 返 回 值: 无
  59.   * 说    明: 无
  60.   */
  61. DSTATUS SPIFLASH_initialize(BYTE lun)
  62. {
  63. #if SPI_FLASH_REBUILD == 1
  64.   static uint8_t startflag=1;
  65. #endif
  66.   Stat = STA_NOINIT;
  67.   /* 初始化SPIFLASHIO外设 */
  68.   MX_SPIFlash_Init();
  69.   /* 获取串行FLASH状态 */
  70.   if(SPI_FLASH_ReadID()==SPI_FLASH_ID)
  71.   {
  72. #if SPI_FLASH_REBUILD == 1
  73.       if(startflag)
  74.       {
  75.         SPI_FLASH_SectorErase(SPI_FLASH_START_SECTOR*SPI_FLASH_SECTOR_SIZE);
  76.                           startflag=0;
  77.       }
  78. #endif
  79.     Stat &=~STA_NOINIT;
  80.   }
  81.   return Stat;
  82. }

  83. /**
  84.   * 函数功能: 串行FLASH状态获取
  85.   * 输入参数: lun : 不用
  86.   * 返 回 值: DSTATUS:串行FLASH状态返回值
  87.   * 说    明: 无
  88.   */
  89. DSTATUS SPIFLASH_status(BYTE lun)
  90. {
  91.   Stat = STA_NOINIT;

  92.   if(SPI_FLASH_ReadID()==SPI_FLASH_ID)
  93.   {
  94.     Stat &= ~STA_NOINIT;
  95.   }
  96.   return Stat;
  97. }

  98. /**
  99.   * 函数功能: 从串行FLASH读取数据到缓冲区
  100.   * 输入参数: lun : 不用
  101.   *           buff:存放读取到数据缓冲区指针
  102.   *           sector:扇区地址(LBA)
  103.   *           count:扇区数目
  104.   * 返 回 值: DSTATUS:操作结果
  105.   * 说    明: 无
  106.   */
  107. DRESULT SPIFLASH_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
  108. {
  109.   sector+=SPI_FLASH_START_SECTOR;      
  110.   SPI_FLASH_BufferRead(buff, sector*SPI_FLASH_SECTOR_SIZE, count*SPI_FLASH_SECTOR_SIZE);
  111.   return RES_OK;
  112. }

  113. /**
  114.   * 函数功能: 将缓冲区数据写入到串行FLASH内
  115.   * 输入参数: lun : 不用
  116.   *           buff:存放待写入数据的缓冲区指针
  117.   *           sector:扇区地址(LBA)
  118.   *           count:扇区数目
  119.   * 返 回 值: DSTATUS:操作结果
  120.   * 说    明: 无
  121.   */
  122. #if _USE_WRITE == 1
  123. DRESULT SPIFLASH_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
  124. {
  125.   uint32_t write_addr;
  126.   /* 扇区偏移7MB,外部Flash文件系统空间放在SPI Flash后面9MB空间 */
  127.   sector+=SPI_FLASH_START_SECTOR;
  128.   write_addr = sector*SPI_FLASH_SECTOR_SIZE;   
  129.   SPI_FLASH_SectorErase(write_addr);
  130.   SPI_FLASH_BufferWrite((uint8_t *)buff,write_addr,count*SPI_FLASH_SECTOR_SIZE);
  131.   return RES_OK;
  132. }
  133. #endif /* _USE_WRITE == 1 */

  134. /**
  135.   * 函数功能: 输入输出控制操作(I/O control operation)
  136.   * 输入参数: lun : 不用
  137.   *           cmd:控制命令
  138.   *           buff:存放待写入或者读取数据的缓冲区指针
  139.   * 返 回 值: DSTATUS:操作结果
  140.   * 说    明: 无
  141.   */
  142. #if _USE_IOCTL == 1
  143. DRESULT SPIFLASH_ioctl(BYTE lun, BYTE cmd, void *buff)
  144. {
  145.   DRESULT res = RES_ERROR;
  146.   
  147.   if (Stat & STA_NOINIT) return RES_NOTRDY;
  148.   
  149.   switch (cmd)
  150.   {
  151.   /* Make sure that no pending write process */
  152.   case CTRL_SYNC :
  153.     res = RES_OK;
  154.     break;
  155.   
  156.   /* 获取串行FLASH总扇区数目(DWORD) */
  157.   case GET_SECTOR_COUNT :
  158.     *(DWORD * )buff = SPI_FLASH_SECTOR_COUNT;       
  159.     res = RES_OK;
  160.     break;
  161.   
  162.   /* 获取读写扇区大小(WORD) */
  163.   case GET_SECTOR_SIZE :
  164.     *(WORD * )buff = SPI_FLASH_SECTOR_SIZE;
  165.     res = RES_OK;
  166.     break;
  167.   
  168.   /* 获取擦除块大小(DWORD) */
  169.   case GET_BLOCK_SIZE :
  170.     *(DWORD * )buff = 1;
  171.     res = RES_OK;
  172.     break;
  173.   
  174.   default:
  175.     res = RES_PARERR;
  176.   }
  177.   
  178.   return res;
  179. }
  180. #endif /* _USE_IOCTL == 1 */

  181. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

diskio.c文件内容
  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2014        */
  3. /*                                                                       */
  4. /*   Portions COPYRIGHT 2015 STMicroelectronics                          */
  5. /*   Portions Copyright (C) 2014, ChaN, all right reserved               */
  6. /*-----------------------------------------------------------------------*/
  7. /* If a working storage control module is available, it should be        */
  8. /* attached to the FatFs via a glue function rather than modifying it.   */
  9. /* This is an example of glue functions to attach various exsisting      */
  10. /* storage control modules to the FatFs module with a defined API.       */
  11. /*-----------------------------------------------------------------------*/
  12. /**
  13.   ******************************************************************************
  14.   * 文件名程: diskio.c
  15.   * 作    者: 硬石嵌入式开发团队
  16.   * 版    本: V1.0
  17.   * 编写日期: 2015-10-04
  18.   * 功    能: FatFS文件系统存储设备输入输出接口实现
  19.   ******************************************************************************
  20.   * 说明:
  21.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  22.   *
  23.   * 淘宝:
  24.   * 论坛:http://www.ing10bbs.com
  25.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  26.   ******************************************************************************
  27.   */

  28. /* 包含头文件 ----------------------------------------------------------------*/
  29. #include "diskio.h"
  30. #include "ff_gen_drv.h"
  31. #include "ff.h"

  32. #if _USE_LFN != 0   // 如果使能长文件名,添加相关解码文件

  33. #if _CODE_PAGE == 936        /* 简体中文:GBK */
  34. #include "option\cc936.c"
  35. #elif _CODE_PAGE == 950        /* 繁体中文:Big5 */
  36. #include "option\cc950.c"
  37. #else                                        /* Single Byte Character-Set */
  38. #include "option\ccsbcs.c"
  39. #endif

  40. #endif

  41. /* 私有类型定义 --------------------------------------------------------------*/
  42. /* 私有宏定义 ----------------------------------------------------------------*/
  43. /* 私有变量 ------------------------------------------------------------------*/
  44. /* 扩展变量 ------------------------------------------------------------------*/
  45. extern Disk_drvTypeDef  disk;

  46. /* 私有函数原形 --------------------------------------------------------------*/
  47. /* 函数体 --------------------------------------------------------------------*/
  48. /**
  49.   * 函数功能: 获取物理设备状态
  50.   * 输入参数: pdrv:物理设备编号
  51.   * 返 回 值: DSTATUS:操作结果
  52.   * 说    明: 无
  53.   */
  54. DSTATUS disk_status (
  55.         BYTE pdrv                /* Physical drive nmuber to identify the drive */
  56. )
  57. {
  58.   DSTATUS stat;
  59.   
  60.   stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
  61.   return stat;
  62. }

  63. /**
  64.   * 函数功能: 初始化物理设备
  65.   * 输入参数: pdrv:物理设备编号
  66.   * 返 回 值: DSTATUS:操作结果
  67.   * 说    明: 无
  68.   */
  69. DSTATUS disk_initialize (
  70.         BYTE pdrv                                /* Physical drive nmuber to identify the drive */
  71. )
  72. {
  73.   DSTATUS stat = RES_OK;
  74.   
  75.   if(disk.is_initialized[pdrv] == 0)
  76.   {
  77.     disk.is_initialized[pdrv] = 1;
  78.     stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
  79.   }
  80.   return stat;
  81. }

  82. /**
  83.   * 函数功能: 从物理设备读取数据到缓冲区
  84.   * 输入参数: pdrv:物理设备编号
  85.   *           buff:存放待写入数据的缓冲区指针
  86.   *           sector:扇区地址(LBA)
  87.   *           count:扇区数目(1..128)
  88.   * 返 回 值: DSTATUS:操作结果
  89.   * 说    明: 无
  90.   */
  91. DRESULT disk_read (
  92.         BYTE pdrv,                /* Physical drive nmuber to identify the drive */
  93.         BYTE *buff,                /* Data buffer to store read data */
  94.         DWORD sector, /* Sector address in LBA */
  95.         UINT count                /* Number of sectors to read */
  96. )
  97. {
  98.   DRESULT res;

  99.   res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
  100.   return res;
  101. }

  102. /**
  103.   * 函数功能: 将缓冲区数据写入到物理设备内
  104.   * 输入参数: pdrv:物理设备编号
  105.   *           buff:存放待写入数据的缓冲区指针
  106.   *           sector:扇区地址(LBA)
  107.   *           count:扇区数目
  108.   * 返 回 值: DSTATUS:操作结果
  109.   * 说    明: SD卡写操作没有使用DMA传输
  110.   */
  111. #if _USE_WRITE == 1
  112. DRESULT disk_write (
  113.         BYTE pdrv,                /* Physical drive nmuber to identify the drive */
  114.         const BYTE *buff,        /* Data to be written */
  115.         DWORD sector,                /* Sector address in LBA */
  116.         UINT count                /* Number of sectors to write */
  117. )
  118. {
  119.   DRESULT res;
  120.   
  121.   res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
  122.   return res;
  123. }
  124. #endif /* _USE_WRITE == 1 */

  125. /**
  126.   * 函数功能: 输入输出控制操作(I/O control operation)
  127.   * 输入参数: pdrv:物理设备编号
  128.   *           cmd:控制命令
  129.   *           buff:存放待写入或者读取数据的缓冲区指针
  130.   * 返 回 值: DSTATUS:操作结果
  131.   * 说    明: 无
  132.   */
  133. #if _USE_IOCTL == 1
  134. DRESULT disk_ioctl (
  135.         BYTE pdrv,                /* Physical drive nmuber (0..) */
  136.         BYTE cmd,                /* Control code */
  137.         void *buff                /* Buffer to send/receive control data */
  138. )
  139. {
  140.   DRESULT res;

  141.   res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
  142.   return res;
  143. }
  144. #endif /* _USE_IOCTL == 1 */

  145. /**
  146.   * 函数功能: 获取实时时钟
  147.   * 输入参数: 无
  148.   * 返 回 值: 实时时钟(DWORD)
  149.   * 说    明: 无
  150.   */
  151. __weak DWORD get_fattime (void)
  152. {
  153.           /* 返回当前时间戳 */
  154.         return          ((DWORD)(2015 - 1980) << 25)        /* Year 2015 */
  155.                         | ((DWORD)10 << 21)                                /* Month 10 */
  156.                         | ((DWORD)4  << 16)                                /* Mday 4 */
  157.                         | ((DWORD)10 << 11)                                /* Hour 10 */
  158.                         | ((DWORD)15 << 5)                                /* Min 15 */
  159.                         | ((DWORD)46 >> 1);                                /* Sec 46 */
  160. }

  161. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

串口调试助手截图.jpg



收藏 3 评论21 发布时间:2016-6-21 10:11

举报

21个回答
guohaidao 回答时间:2016-6-21 15:53:59
Cube库虽然好用,不过Bug太多。有空可以试试看RTC的代码生成,连初始化都过不去,如何更好的让人使用呢?
haohao663 回答时间:2016-6-21 16:23:18
guohaidao 发表于 2016-6-21 15:53
Cube库虽然好用,不过Bug太多。有空可以试试看RTC的代码生成,连初始化都过不去,如何更好的让人使用呢? ...

RTC已经有例程的啦
【HAL库每天一例】第036例:RTC-实时时钟
https://www.stmcu.org.cn/module/ ... &fromuid=331315
(出处: 意法半导体STM32/STM8技术社区)
haohao663 回答时间:2019-4-29 15:52:11
289466080 发表于 2019-4-23 10:54
百度分享链接失效了,参考资料可以给我一份吗? 感谢~

硬石开源资料下载链接(该帖总是最新资料)
http://www.ing10bbs.com/forum.ph ... =1458&fromuid=4
(出处: 硬石社区)
yanhaijian 回答时间:2016-6-21 15:08:49
STM32CubeMX确实让开发变得更便利。
guohaidao 回答时间:2016-6-21 15:54:53
楼主有支持USB的MSD设备并实现FAT的工程吗?
haohao663 回答时间:2016-6-21 16:26:39
guohaidao 发表于 2016-6-21 15:54
楼主有支持USB的MSD设备并实现FAT的工程吗?

手头上只有USB MSC例程(实现模拟U盘效果)
不知需要不?
guohaidao 回答时间:2016-6-22 11:29:08
haohao663 发表于 2016-6-21 16:26
手头上只有USB MSC例程(实现模拟U盘效果)
不知需要不?

需要,非常感谢:)
guohaidao 回答时间:2016-6-22 11:33:51
haohao663 发表于 2016-6-21 16:26
手头上只有USB MSC例程(实现模拟U盘效果)
不知需要不?

http://www.ing10bbs.com/forum.ph ... &extra=page%3D1
这个路径对吧。
guohaidao 回答时间:2016-6-22 11:35:20
最好有360云盘的分享链接,哈哈,毕竟360云盘比百度大。
haohao663 回答时间:2016-6-22 12:12:00
都是很大的,现在上传到360云盘
360云盘链接:http://yunpan.cn/OcPiRp3wEcA92u  访问密码 cfb6
上行网速不给力,等下午就可以下载
Ian-392967 回答时间:2016-7-1 22:35:32
多谢分享
qq244141084 回答时间:2018-9-20 09:35:51
亲,连接失效了
hhhhhhhaa 回答时间:2018-10-18 09:45:25
求助一个STM32F103VCT6与AT45DB081芯片通讯添加文件管理系统FATFS,SPI2的接口的示例
hhhhhhhaa 回答时间:2018-12-27 11:45:26
什么时候上传视频啊?
289466080 回答时间:2019-4-17 21:26:21
共享资料还有吗?失效了。
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版