基于stm32的USB虚拟U盘+FATFS+W25Q64

news2024/12/25 8:59:46

基于stm32的USB虚拟U盘+FATFS+W25Q64

本文目标:基于stm32的USB虚拟U盘+FATFS+W25Q64

按照本文的描述,简单跑通USB的MSC类来进行简单交互。

先决条件:拥有C语言基础,装有编译和集成的开发环境,比如:Keil uVision5

使用外设:USB、USART1、GPIO、SPI1

HAL库版本:STM32F4xx HAL Driver version number 1.26.0

STMCubeMX版本:6.10.0

Keil uVision5版本:V5.38.0.0

实验目的

新手学习,在之前的有篇文章中实现了USB的CDC类,觉得usb的实验可做的实验还挺多的,然后在网络搜索了一下相关实验,发现一个博主写了一个类似的实验,上手性挺好的,于是基于他的博客知识自己进行复刻一下,本文主要结合自己的编程经验有了这篇文章,能够实现简单的USB模拟U盘的实验。在本次实验中,将使用STM32作为从设备使用USB的MSC类,在W25Q64存储ic上移植FATFS。

场景使用原理图

在我的这个应用场景中,原理图的内容如下:

在这里插入图片描述

在这里插入图片描述

基于以上的原理设计,使用usb接口进行模拟U盘实验。USB相对来说是一个比较复杂的东西,涉及的东西挺多,学得也不是很深入,只能简单的跑通实验。

配置USB_OTG_FS

打开STMCubeMX工具,找到交互通讯,配置一下USB_OTG_FS

在这里插入图片描述

配置USB类型

找到USB_DEVICE,配置一下MSC的类型。

在这里插入图片描述

配置spi

在这里插入图片描述

配置FAFTS

在这里插入图片描述

配置系统时钟

在这里插入图片描述

修改usbd_storage_if.c函数

配置好底层之后,生成代码,主要是去修改这个接口配置函数

在这里插入图片描述

在usbd_storage_if.c中,我修改了下面的部分内容

在这里插入图片描述

int8_t STORAGE_IsReady_FS(uint8_t lun)函数修改

在这里插入图片描述

读函数修改

在这里插入图片描述

写函数修改

在这里插入图片描述

修改SPI_diskio.c

在这里插入图片描述

将底层的一些函数替换成我现有的硬件的底层函数。

上层调用

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  MX_SPI1_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  	bsp_InitSPIBus();	/* 配置SPI总线 */		
	bsp_InitSFlash();	/* 初始化SPI 串行Flash */
//  W25QXX_Init();
//  W25QXX_Write((uint8_t*)TEXT_Buffer,ADDERSS_FLASH,SIZE);		
//  W25QXX_Read(datatemp,ADDERSS_FLASH,SIZE);	
    FatfsTest();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

void FatfsTest(void)
{
	mount_disk();		    //文件系统注册
    format_disk();		  //格式化文件系统
//	fileSystemInit();
	create_file();		    //建立文件并写入"hello666\n"  
	read_file();		      //读取文件放到ReadBuffer中
}

在上层的代码中,实现FatfsTest这个函数。参考代码如上。

上机现象

烧写运行程序后,接上 USB 线,在电脑上可以识别出 USB 的大容量存储设备,如下:

在这里插入图片描述

同时会模拟出一个U盘,

在这里插入图片描述

u盘里面有个TEST.TXT的文件,内容和代码中一致

在这里插入图片描述

后记

对于虚拟的U盘大小,我使用的是W25Q64FV这颗,有 128 个 Block,每个 Block 大小 64KB。每个 Block 有 16 个 Sector,每个 Sector 大小 4KB。每个 Sector 有 16 个 Page,每个 Page 大小是 256 字节。

所以在代码spi_diskio.c中定义:

static volatile DSTATUS Stat = STA_NOINIT;

#define PAGE_SIZE       256
#define SECTOR_SIZE     4096
#define SECTOR_COUNT	  128*16
#define BLOCK_SIZE	    65536
#define FLASH_PAGES_PER_SECTOR	SECTOR_SIZE/PAGE_SIZE

工程调试起来挺费劲的,还是需要多实践。但是格式化后并没有我想象的8M内存,fatfs文件系统内部占据了一些内存,后期有机会学习文件系统时在进行研究一下,还有看到有些人是使用内部的ram来完成实验的,后期找到好的相关资料在进行分享。

本文记录到此,算是自己工程的一次实践,本文完!!感谢阅读,感谢关注。

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/89267829

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643620.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如果还有机会再跟芒格共度一天,巴菲特想做什么?

这是芒格因离世而缺席的第一年,但他的身影却无处不在。问答环节,巴菲特会不小心脱口而出“查理,该你回答了”,他也称,与芒格在一起的时间比独处要快乐。 可以说,虽然99岁的芒格因离世而缺席了2024年伯克希…

记录几种排序算法

十种常见排序算法可以分类两大类别:比较类排序和非比较类排序。 常见的快速排序、归并排序、堆排序以及冒泡排序等都属于比较类排序算法。比较类排序是通过比较来决定元素间的相对次序,其时间复杂度不能突破 O(nlogn)。在冒泡排序之类的排序中&…

Python基础详解一

一&#xff0c;print打印 print("hello word") print(hello word) 双引号和单引号都可以 二&#xff0c;数据类型 Python中常用的有6种值的类型 输出类型信息 print(type(11)) print(type("22")) print(type(22.2)) <class int> <class str&…

Mybatis进阶2

Mybatis进阶1-CSDN博客 Mybatis入门-CSDN博客 Mybatis入门2-CSDN博客 我们接下来要学习Mybatis的高级查询 我们先在数据库中准备我们需要的数据表 teacher表 课程表&#xff1a;与教师表是一对多的关系&#xff0c;所以有一个外键字段 学生表 由于学生表和课程表是多对多的…

鸿蒙ArkTs开发,仿抖音个人中心header 下拉放大

如果是iOS 或者android 上实现&#xff0c;可以用Scollview 的contentOffset 来实现&#xff0c;然而在鸿蒙ets中该如何实现&#xff1f;废话不多说开始撸代码 第一步、实现一个header // 创建header&#xff0c;准备一张背景图片BuilderHeaderBuilder(){Column() {Row() {Ima…

算法入门<一>:C++各种排序算法详解及示例源码

1、排序算法 排序算法&#xff08;sorting algorithm&#xff09;用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用&#xff0c;因为有序数据通常能够被更高效地查找、分析和处理。 1.1 评价维度 运行效率&#xff1a;我们期望排序算法的时间复杂度尽量低&#xf…

C语言学习【C语言基本数据类型】

C语言学习【C语言基本数据类型】 整数溢出 /* 整数溢出 */ #include "stdio.h" /* Last Modified Time: 2024-05-05 17:53:49 */int main(void) {int i 2147483647;unsigned int j 4294967295;printf("%d %d %d\n", i, i1, i2);printf("%u %u %u\…

【数据结构初阶】直接插入排序

最近浅学了直接插入排序&#xff0c;写个博客做笔记&#xff01;笔记功能除外若能对读者老爷有所帮助最好不过了&#xff01; 直接插入排序是插入排序的一种&#xff0c;那么介绍直接插入排序之前先介绍一下常见的排序算法&#xff01; 目录 1.常见的排序算法 2.直接插入排…

500行代码实现贪吃蛇(1)

文章目录 目录1. Win32 API 介绍1.1 Win32 API1.2 控制台程序&#xff08;Console&#xff09;1.3 控制台屏幕上的坐标COORD1.4 [GetStdHandle](https://learn.microsoft.com/zh-cn/windows/console/getstdhandle)1.5 [GetConsoleCursorInfo](https://learn.microsoft.com/zh-c…

项目经理【人】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 【环境】任务 【环境】绩效 【人】概述 【人】原则 一、共创模式 1.1 共创模式 二、干系人的影响力强度和态度 2.1 干系人影响力 2.2 干系人态度 2.3 干系人管理 三、干系人权力…

Java17 --- SpringCloud之Gateway

目录 一、Gateway网关创建 1.1、创建微服务子工程9527及配置和依赖 1.1.1、pom依赖 1.1.2、yml配置 1.1.3、主启动类并测试入驻consul 二、实现路由映射 2.1、服务8001新增测试代码 2.2、修改9527服务yml配置文件 2.3、远程调用接口加gateway 2.3.1、新增80服务测…

【Android学习】简单的登录页面和业务逻辑实现

实现功能 1 登录页&#xff1a;密码登录和验证码登录 2 忘记密码页&#xff1a;修改密码 3 页面基础逻辑 java代码 基础页面 XML login_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.and…

C++静态数组和C语言静态数组的区别( array,int a[])

目录 一、区别 1、越界读&#xff0c;检查不出来 2、越界写&#xff0c;抽查&#xff0c;可能检查不出来&#xff0c;有局限性 二、array缺点 一、区别 C语言的静态数组int a[]; 静态数组的越界检查不稳定的&#xff1a; 1、越界读&#xff0c;检查不出来 2、越界写&#x…

开发一款简易APP

希望打开APP后,显示当前时间..可能不实用,重在体验 安装Flutter 如果在arm架构的 Mac 电脑上进行开发&#xff0c;需要安装 Rosetta 2, 因为一些辅助工具需要&#xff0c;可通过手动运行下面的命令来安装&#xff1a; sudo softwareupdate --install-rosetta --agree-to-licens…

一篇文章带你深入了解“指针”

一篇文章带你深入了解“指针” 内存和地址了解指针指针类型const修饰指针指针的运算指针与整数之间的运算指针与指针之间的运算指针的关系运算 void* 指针传值调用和传址调用数组和指针的关系野指针野指针的形成原因规避野指针 二级指针字符指针指针数组数组指针数组传参一维数…

动态炫酷的新年烟花网页代码

烟花效果的实现可以采用前端技术&#xff0c;如HTML、CSS和JavaScript。通过结合动画、粒子效果等技术手段&#xff0c;可以创建出独特而炫目的烟花效果。同时&#xff0c;考虑到性能和兼容性&#xff0c;需要确保效果在各种设备上都能够良好运行。 效果显示http://www.bokequ.…

Transformer中的数据输入构造

文章目录 1. 文本内容2. 字典构造2.1 定义一个类用于字典构造2.2 拆分文本2.3 构造结果 3. 完整代码 1. 文本内容 假如我们有如下一段文本内容&#xff1a; Optics It is the branch of physics that studies the behaviour and properties of light . Optical Science 这段…

代码随想录Day 37|Leetcode|Python|● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 II 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结…

Java web第五次作业

1.在idea中配置好数据源 2、视频案例中只给出了查询所有结果的示例&#xff0c;请自己完成添加、删除、修改操作的代码。以下供参 考。 Delete("delete from emp where id#{id}") public void delete(Integer id); 测试代码 Test public void testDelete(){ empMa…

AI产品经理需要懂的技术全景图

AI产品经理需要懂技术&#xff0c;以便与算法工程师同频沟通&#xff0c;以及合理管控AI项目进度。 项目掌握内容掌握边界数学统计学基础概念常见概念知道、了解模型构建 模型构建流程涉及角色每个角色工作内容清楚知道每个角色该做什么&#xff0c;需要花费多少成本&#xff…