STM32CubeMX通过FatFS读写U盘

24 篇文章 12 订阅
3 篇文章 1 订阅

最近出现了使用STM32读写U盘的需求,本着自己也出了好多良心博客的份上就像偷懒抄一篇CSDN,但是鉴于某些博主这点小东西都要收费、还不公开源码,一气之下准备自己写一篇博客来谴责某些不良心的博主;(上述气话,接下来上干货)

大致思路

STM32读写U盘主要分为以下几个方面:
1、文件系统(抽象层,以统一方式对不同外设进行读写)
2、USB_Host(USB硬件驱动,维持USB的正常工作)
3、FreeRTOS(操作系统,鉴于各位可能右用到操作系统的需求加上,也可以裸机跑)

具体思想如下:(是不是很简单,就搞不懂这点事为啥要收费)

FatFS
USB_Host
需要存储的数据
文件系统规范格式
USB文件

为了方便观察文件是否真实写入到U盘,所以我的想法是在U盘写一个文件,内部写一些数据,然后重新读这个文件,并通过串口将读出来的东西显示出来!

接下来就要配置STM32CubeMX了(我使用的板子是STM32F407IGTx,串口使用串口1,对应收发引脚是PB6和PB7,各位看官可以根据自己的需求更改)

使用的是STM32CubeMX6.3.0,对应的F4芯片的包也要更新,不然会卡死在USB的初始化(被坑过,请勿嘲笑)

具体操作

1、首先选择芯片:STM32F407IGTx
在这里插入图片描述
2、配置RCC和SYS(我用的是SWD下载方式)
在这里插入图片描述
因为一会儿要配置FreeRTOS,所以时钟源定义为TIM1
在这里插入图片描述
3、配置串口1为波特率115200,1停止位8数据位无校验(端口自行定义)
在这里插入图片描述
4、配置USB_OTG_FS(默认即可)
在这里插入图片描述
5、配置USB_HOST(配置为大容量存储,默认即可)
其中,USBH_DEBUG_LEVEL是用来检查u盘状态的,可以通过串口反馈usb的状态信息,由于我已经测试过了,这里我就配置为0,不返回信息
在这里插入图片描述
6、配置文件系统FATFS(按图配置即可)
在这里插入图片描述
7、配置FreeRTOS,此处为了简单配置成一个默认任务即可,主任务的堆需要配置的大一点,因为存储数据需要定义较大的空间,定义的堆太小会导致代码跳进硬件错误(Hard_Fault)
在这里插入图片描述
8、配置时钟树(我的高速晶振为8MHz,大家按自己的板子配置)
在这里插入图片描述
9、配置项目管理界面(我用Keil写,IED配置为MDK-ARM,堆和栈都需要设大一些,防止数据溢出导致的Hard_Fault)
在这里插入图片描述
代码生成器如图配置,我个人习惯
在这里插入图片描述
配置完成后点击右上方生成代码即可!(出现警告不用管,那个是因为某些USB需要通过MCU的IO或外部的IIC芯片的IO控制三极管给USB供电,需要在USB内配置供电IO的接口,我的是5V直供,故不管)
在这里插入图片描述

代码部分

打开项目之后直接转到freertos.c下,找到刚刚建立的任务,可见CubeMX已经帮我们对USB进行初始化了
在这里插入图片描述
1、引入对应的头文件
此处我需要使用到串口、文件系统的USB相关数据,故在/* USER CODE BEGIN Includes */后追加包含对应的头文件:

/* USER CODE BEGIN Includes */
#include "usart.h"
#include "usb_host.h"
#include "fatfs.h"
/* USER CODE END Includes */

2、添加相关变量并执行对应的FatFS操作(说明看注释)此部分代码在for循环中添加

 if(Appli_state == APPLICATION_READY)//U盘已经加载完成
        {
          if(status == 0)//U盘加载后只运行一次
          {
            status = 1;
            retUSBH=f_mount(&USBHFatFS, (TCHAR const*)USBHPath, 1);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"挂载U盘成功!\r\n",14,100);
            }
            //写入文件测试
            HAL_UART_Transmit(&huart1,(uint8_t*)"写入文件测试!\r\n",15,100);
            retUSBH = f_open(&USBHFile,(const char*)"测试.txt",FA_CREATE_ALWAYS|FA_WRITE);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"打开文件\"测试.txt\"成功!\r\n",25,100);
            }
			
			retUSBH = f_lseek(&USBHFile,f_size(&USBHFile));
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"指针移动到文件末尾成功!\r\n",25,100);
            }
			
            retUSBH = f_write(&USBHFile,FileBuf,18,&bw);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"写入文件成功!\r\n",15,100);
            }
            retUSBH = f_close(&USBHFile);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"关闭文件成功!\r\n\r\n",17,100);
            }
            //读取文件测试
            HAL_UART_Transmit(&huart1,(uint8_t*)"读取文件测试!\r\n",15,100);
            retUSBH = f_open(&USBHFile,(const char*)"测试.txt",FA_OPEN_EXISTING|FA_READ);//打开文件
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"打开文件\"测试.txt\"成功!\r\n",25,100);
            }
            retUSBH = f_read(&USBHFile,FileBuf,18,&bw);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"读取文件成功!文件内容:",23,100);
              HAL_UART_Transmit(&huart1,FileBuf,bw,100);
            }
            retUSBH = f_close(&USBHFile);
            if(retUSBH==FR_OK)
            {
              HAL_UART_Transmit(&huart1,(uint8_t*)"关闭文件成功!\r\n",15,100);
			}
		}
	}
		
	if(Appli_state == APPLICATION_IDLE)//U盘未插入
	{
		status = 0;//等待下次U盘插入则重新写入
	}

测试部分

1、编译并下载代码
2、打开对应的串口调试工具,把串口接到PC上
3、启动板子并插入U盘(小于等于8G)大了读不出来,会导致设备死机。
手头没有8GU盘。测试结果先欠着,下次找个U盘搞出来又发

  • 23
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值