微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 第048例:SPI-基于串行Flash&SD卡的FatFS文件系统

第048例:SPI-基于串行Flash&SD卡的FatFS文件系统

时间:10-02 整理:3721RD 点击:
【HAL库每天一例】系列例程从今天开始持续更新。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:http://pan.baidu.com/s/1i574oPv
密码:r3s3

(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-048. SPI-基于串行Flash&SD卡的FatFS文件系统)
/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-048. SPI-基于串行Flash&SD卡的FatFS文件系统
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:www ing10bbs com
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */
【1】例程简介
  SDIO是安全输入输出接口,采用在SD卡上。SD卡做为一种性价比极高的存储介质,在生活中非常
普遍可见。
  串行Flash用于存储数据。YS-F1Pro开发板集成了一个16M字节的W25Q128串行Flash芯片,可以
用于存放数据。该芯片使用SPI1通信接口
  FatFS是一个专门为嵌入式开发的开源小型文件系统。FatFS可以提供丰富的文件操作函数,方便
文件操作,我们可以在串行Flash空间上移植FatFS文件系统。
  
【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
  将一张小于32G大小的Micro SD卡插入到开发板上的SD卡槽内,使用开发板配套的MINI USB线连
接到开发板标示“调试串口”字样的MIMI USB接口(需要安装驱动),在电脑端打开串口调试助手
工具,设置参数为115200 8-N-1。下载完程序之后,在串口调试助手窗口可接收到信息。
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/





main.c文件内容

  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.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 "stm32f1xx_hal.h"
  19. #include "usart/bsp_debug_usart.h"
  20. #include "ff.h"
  21. #include "ff_gen_drv.h"
  22. #include "drivers\spiflash_diskio.h"
  23. #include "drivers\sd_diskio.h"

  24. /* 私有类型定义 --------------------------------------------------------------*/
  25. /* 私有宏定义 ----------------------------------------------------------------*/
  26. /* 私有变量 ------------------------------------------------------------------*/
  27. char SPIFLASHPath[4];             /* 串行Flash逻辑设备路径 */
  28. char SDPath[4];                   /* SD卡逻辑设备路径 */

  29. FATFS fs;                                                                                                        /* FatFs文件系统对象 */
  30. FIL file;                                                                                                        /* 文件对象 */
  31. FRESULT f_res;                    /* 文件操作结果 */
  32. UINT fnum;                                                      /* 文件成功读写数量 */
  33. BYTE ReadBuffer[1024]={0};        /* 读缓冲区 */
  34. BYTE WriteBuffer[]= "欢迎使用硬石STM32开发板 今天是个好日子,新建文件系统测试文件\n";/* 写缓冲区*/  

  35. /* 扩展变量 ------------------------------------------------------------------*/
  36. /* 私有函数原形 --------------------------------------------------------------*/
  37. static void printf_fatfs_error(FRESULT fresult);

  38. /* 函数体 --------------------------------------------------------------------*/
  39. /**
  40.   * 函数功能: 系统时钟配置
  41.   * 输入参数: 无
  42.   * 返 回 值: 无
  43.   * 说    明: 无
  44.   */
  45. void SystemClock_Config(void)
  46. {
  47.   RCC_OscInitTypeDef RCC_OscInitStruct;
  48.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  49.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  50.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  51.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREdiv_div1;
  52.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  53.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  54.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍频,得到72MHz主时钟
  55.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  56.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  57.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  58.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHz
  59.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_div1;              // AHB时钟:72MHz
  60.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_div2;               // APB1时钟:36MHz
  61.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_div1;               // APB2时钟:72MHz
  62.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  63.          // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
  64.         // HAL_RCC_GetHCLKFreq()/100000         10us中断一次
  65.         // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  66.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器
  67.   /* 系统滴答定时器时钟源 */
  68.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  69.   /* 系统滴答定时器中断优先级配置 */
  70.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  71. }

  72. /**
  73.   * 函数功能: 主函数.
  74.   * 输入参数: 无
  75.   * 返 回 值: 无
  76.   * 说    明: 无
  77.   */
  78. int main(void)
  79. {  
  80.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  81.   HAL_Init();
  82.   /* 配置系统时钟 */
  83.   SystemClock_Config();

  84.   /* 初始化串口并配置串口中断优先级 */
  85.   MX_DEBUG_USART_Init();
  86.   printf("****** 这是一个基于串行FLASH的FatFS文件系统实验 ******\n");
  87.   
  88. /**************************************************************************/
  89.   /* 注册一个FatFS设备:串行FLASH */
  90.   if(FATFS_LinkDriver(&SPIFLASH_Driver, SPIFLASHPath) == 0)
  91.   {
  92.     //在串行FLASH挂载文件系统,文件系统挂载时会对串行FLASH初始化
  93.     f_res = f_mount(&fs,(TCHAR const*)SPIFLASHPath,1);
  94.     printf_fatfs_error(f_res);
  95.     /*----------------------- 格式化测试 ---------------------------*/  
  96.     /* 如果没有文件系统就格式化创建创建文件系统 */
  97.     if(f_res == FR_NO_FILESYSTEM)
  98.     {
  99.       printf("》串行FLASH还没有文件系统,即将进行格式化...\n");
  100.       /* 格式化 */
  101.       f_res=f_mkfs((TCHAR const*)SPIFLASHPath,0,0);                                                        
  102.       
  103.       if(f_res == FR_OK)
  104.       {
  105.         printf("》串行FLASH已成功格式化文件系统。\n");
  106.         /* 格式化后,先取消挂载 */
  107.         f_res = f_mount(NULL,(TCHAR const*)SPIFLASHPath,1);                        
  108.         /* 重新挂载        */                        
  109.         f_res = f_mount(&fs,(TCHAR const*)SPIFLASHPath,1);
  110.       }
  111.       else
  112.       {
  113.         printf("《《格式化失败。》》\n");
  114.         while(1);
  115.       }
  116.     }
  117.     else if(f_res!=FR_OK)
  118.     {
  119.       printf("!串行FLASH挂载文件系统失败。(%d)\n",f_res);
  120.       printf_fatfs_error(f_res);
  121.       while(1);
  122.     }
  123.     else
  124.     {
  125.       printf("》文件系统挂载成功,可以进行读写测试\n");
  126.     }
  127.    
  128.     /*----------------------- 文件系统测试:写测试 -----------------------------*/
  129.     /* 打开文件,如果文件不存在则创建它 */
  130.     printf("****** 即将进行文件写入测试... ******\n");        
  131.     f_res = f_open(&file, "FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
  132.     if ( f_res == FR_OK )
  133.     {
  134.       printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\n");
  135.       /* 将指定存储区内容写入到文件内 */
  136.       f_res=f_write(&file,WriteBuffer,sizeof(WriteBuffer),&fnum);
  137.       if(f_res==FR_OK)
  138.       {
  139.         printf("》文件写入成功,写入字节数据:%d\n",fnum);
  140.         printf("》向文件写入的数据为:\n%s\n",WriteBuffer);
  141.       }
  142.       else
  143.       {
  144.         printf("!文件写入失败:(%d)\n",f_res);
  145.       }   
  146.       /* 不再读写,关闭文件 */
  147.       f_close(&file);
  148.     }
  149.     else
  150.     {        
  151.       printf("!打开/创建文件失败。\n");
  152.     }
  153.    
  154.     /*------------------- 文件系统测试:读测试 ------------------------------------*/
  155.     printf("****** 即将进行文件读取测试... ******\n");
  156.     f_res = f_open(&file, "FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ);         
  157.     if(f_res == FR_OK)
  158.     {
  159.       printf("》打开文件成功。\n");
  160.       f_res = f_read(&file, ReadBuffer, sizeof(ReadBuffer), &fnum);
  161.       if(f_res==FR_OK)
  162.       {
  163.         printf("》文件读取成功,读到字节数据:%d\n",fnum);
  164.         printf("》读取得的文件数据为:\n%s \n", ReadBuffer);        
  165.       }
  166.       else
  167.       {
  168.         printf("!文件读取失败:(%d)\n",f_res);
  169.       }               
  170.     }
  171.     else
  172.     {
  173.       printf("!打开文件失败。\n");
  174.     }
  175.     /* 不再读写,关闭文件 */
  176.     f_close(&file);
  177.     /* 不再使用,取消挂载 */
  178.     f_res = f_mount(NULL,(TCHAR const*)SPIFLASHPath,1);        
  179.   }  
  180.   
  181.   /* 注销一个FatFS设备:串行FLASH */
  182.   FATFS_UnLinkDriver(SPIFLASHPath);
  183.   
  184. /**************************************************************************/
  185.   /* 注册一个FatFS设备:SD卡 */
  186.   if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
  187.   {
  188.     //在SD卡挂载文件系统,文件系统挂载时会对SD卡初始化
  189.     f_res = f_mount(&fs,(TCHAR const*)SDPath,1);
  190.     printf_fatfs_error(f_res);
  191.     /*----------------------- 格式化测试 ---------------------------*/  
  192.     /* 如果没有文件系统就格式化创建创建文件系统 */
  193.     if(f_res == FR_NO_FILESYSTEM)
  194.     {
  195.       printf("》SD卡还没有文件系统,即将进行格式化...\n");
  196.       /* 格式化 */
  197.       f_res=f_mkfs((TCHAR const*)SDPath,0,0);                                                        
  198.       
  199.       if(f_res == FR_OK)
  200.       {
  201.         printf("》SD卡已成功格式化文件系统。\n");
  202.         /* 格式化后,先取消挂载 */
  203.         f_res = f_mount(NULL,(TCHAR const*)SDPath,1);                        
  204.         /* 重新挂载        */                        
  205.         f_res = f_mount(&fs,(TCHAR const*)SDPath,1);
  206.       }
  207.       else
  208.       {
  209.         printf("《《格式化失败。》》\n");
  210.         while(1);
  211.       }
  212.     }
  213.     else if(f_res!=FR_OK)
  214.     {
  215.       printf("!SD卡挂载文件系统失败。(%d)\n",f_res);
  216.       printf_fatfs_error(f_res);
  217.       while(1);
  218.     }
  219.     else
  220.     {
  221.       printf("》文件系统挂载成功,可以进行读写测试\n");
  222.     }
  223.    
  224.     /*----------------------- 文件系统测试:写测试 -----------------------------*/
  225.     /* 打开文件,如果文件不存在则创建它 */
  226.     printf("****** 即将进行文件写入测试... ******\n");        
  227.     f_res = f_open(&file, "FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
  228.     if ( f_res == FR_OK )
  229.     {
  230.       printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\n");
  231.       /* 将指定存储区内容写入到文件内 */
  232.       f_res=f_write(&file,WriteBuffer,sizeof(WriteBuffer),&fnum);
  233.       if(f_res==FR_OK)
  234.       {
  235.         printf("》文件写入成功,写入字节数据:%d\n",fnum);
  236.         printf("》向文件写入的数据为:\n%s\n",WriteBuffer);
  237.       }
  238.       else
  239.       {
  240.         printf("!文件写入失败:(%d)\n",f_res);
  241.       }   
  242.       /* 不再读写,关闭文件 */
  243.       f_close(&file);
  244.     }
  245.     else
  246.     {        
  247.       printf("!打开/创建文件失败。\n");
  248.     }
  249.    
  250.     /*------------------- 文件系统测试:读测试 ------------------------------------*/
  251.     printf("****** 即将进行文件读取测试... ******\n");
  252.     f_res = f_open(&file, "FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ);         
  253.     if(f_res == FR_OK)
  254.     {
  255.       printf("》打开文件成功。\n");
  256.       f_res = f_read(&file, ReadBuffer, sizeof(ReadBuffer), &fnum);
  257.       if(f_res==FR_OK)
  258.       {
  259.         printf("》文件读取成功,读到字节数据:%d\n",fnum);
  260.         printf("》读取得的文件数据为:\n%s \n", ReadBuffer);        
  261.       }
  262.       else
  263.       {
  264.         printf("!文件读取失败:(%d)\n",f_res);
  265.       }               
  266.     }
  267.     else
  268.     {
  269.       printf("!打开文件失败。\n");
  270.     }
  271.     /* 不再读写,关闭文件 */
  272.     f_close(&file);
  273.    
  274.     /* 不再使用,取消挂载 */
  275.     f_res = f_mount(NULL,(TCHAR const*)SDPath,1);        
  276.   }
  277.    
  278.   /* 注销一个FatFS设备:SD卡 */
  279.   FATFS_UnLinkDriver(SDPath);
  280.   
  281.   /* 无限循环 */
  282.   while (1)
  283.   {
  284.   }
  285. }

  286. /**
  287.   * 函数功能: FatFS文件系统操作结果信息处理.
  288.   * 输入参数: FatFS文件系统操作结果:FRESULT
  289.   * 返 回 值: 无
  290.   * 说    明: 无
  291.   */
  292. static void printf_fatfs_error(FRESULT fresult)
  293. {
  294.   switch(fresult)
  295.   {
  296.     case FR_OK:                   //(0)
  297.       printf("》操作成功。\n");
  298.     break;
  299.     case FR_DISK_ERR:             //(1)
  300.       printf("!硬件输入输出驱动出错。\n");
  301.     break;
  302.     case FR_INT_ERR:              //(2)
  303.       printf("!断言错误。\n");
  304.     break;
  305.     case FR_NOT_READY:            //(3)
  306.       printf("!物理设备无法工作。\n");
  307.     break;
  308.     case FR_NO_FILE:              //(4)
  309.       printf("!无法找到文件。\n");
  310.     break;
  311.     case FR_NO_PATH:              //(5)
  312.       printf("!无法找到路径。\n");
  313.     break;
  314.     case FR_INVALID_NAME:         //(6)
  315.       printf("!无效的路径名。\n");
  316.     break;
  317.     case FR_DENIED:               //(7)
  318.     case FR_EXIST:                //(8)
  319.       printf("!拒绝访问。\n");
  320.     break;
  321.     case FR_INVALID_OBJECT:       //(9)
  322.       printf("!无效的文件或路径。\n");
  323.     break;
  324.     case FR_WRITE_PROTECTED:      //(10)
  325.       printf("!逻辑设备写保护。\n");
  326.     break;
  327.     case FR_INVALID_DRIVE:        //(11)
  328.       printf("!无效的逻辑设备。\n");
  329.     break;
  330.     case FR_NOT_ENABLED:          //(12)
  331.       printf("!无效的工作区。\n");
  332.     break;
  333.     case FR_NO_FILESYSTEM:        //(13)
  334.       printf("!无效的文件系统。\n");
  335.     break;
  336.     case FR_MKFS_ABORTED:         //(14)
  337.       printf("!因函数参数问题导致f_mkfs函数操作失败。\n");
  338.     break;
  339.     case FR_TIMEOUT:              //(15)
  340.       printf("!操作超时。\n");
  341.     break;
  342.     case FR_LOCKED:               //(16)
  343.       printf("!文件被保护。\n");
  344.     break;
  345.     case FR_NOT_ENOUGH_CORE:      //(17)
  346.       printf("!长文件名支持获取堆空间失败。\n");
  347.     break;
  348.     case FR_TOO_MANY_OPEN_FILES:  //(18)
  349.       printf("!打开太多文件。\n");
  350.     break;
  351.     case FR_INVALID_PARAMETER:    // (19)
  352.       printf("!参数无效。\n");
  353.     break;
  354.   }
  355. }
  356. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

复制代码





谢谢分享!

很不错的项目例程

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top