在项目应用中,经常会有对外交换数据的需求。USB接口读写U盘无疑是一种颇为方便的选择。在这一篇中,我们就来讨论如何在STM32上实现USB主机读写U盘文件的方法。

1、应用概述

  在我们的产品上有这样一个需求,希望通过大容量的U盘存取数据。我们来分析一下这个需求的具体内容。

  首先在硬件上我们需要有相应的USB端口,这一点在产品设计时就已经考虑并实现,所以硬件方面我们就不再过多的表述。

  其次我们需要为这个USB的硬件接口编写驱动,就是实现USB端口的底层操作,如IO配置、终端处理等,这是移植的主要工作。

  再者我们需要移植面向大容量存储的USB Host库,这也是我们需要做的工作之一。其实USB主机库本身并不需要我们做什么,但我们要清楚它需要我们提供些什么。

  最后我们还要实现一个应用层操作,它将用于实现我们的读写数据的最终目标。在开发过程中这其实是重点工作,但在这篇文章中他不是重点。我们主要是要实现USB主机库面向大容量存储设备的移植问题。

2、USB库的移植

  在这个产品中使用的是STM32F407作为控制单元,所以我们使用STM32的USB主机库来实现。接下来就看一看STM32的USB主机库移植问题。我们使用STM32CubeMX来实现USB的相关配置。

  第一步,我们来配置USB的连接端口,我们连接中找到USB_OTG_FS,在右侧的选项中选择Host_Only,如下图所示:

  然后在Middleware中找到USB_HOST,并在右侧“Class for FS IP”中选择“Mass Storage Host Class”配置为大容量存储设备。如下图所示:

  接着在Middleware中找到FATFS,并在右侧选中“USB Disk”。下方的参数中,将CODE_PAGE设置为简体中文。具体如下图所示:

  最后需要在终端中将USB的全局中断选中,并设定中断级别,具体如下图所示:

  中断必须打开,中断级别可以根据需要设置。中断会监测USB的状态,所以中断不打开,USB库无法工作。完成上述配置后就可以生成源码了,然后在此基础上进一步开发。

  对于STM32的USB主机库的移植有两个文件是必须要写的,就是usbh_conf.c和usbh_conf.h文件。这两个文件文件实现USB的基础配置,以及库需要调用的基础函数。在我们使用STM32CubeMX来配置和建立项目时,usbh_conf.c和usbh_conf.h文件也一并生成好了,不需要我们再去单独编写这些平台相关的函数。

3、应用实现

  因为使用STM32CubeMX来配置和建立项目的缘故,使得USB主机库的移植非常简单,但我们还需要编写应用层的代码。应用层代码主要实现两个方面的内容:一是编写主机库需要回调的获取USB状态的函数;二是轮询处理主机库中的USBH_Process函数以及我们需要处理的工作。

  首先来看应用处理回调函数。这个函数是主机库所要求的,用于处理与用户应用相关的操作,这个函数的原型如下:

  void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t id)

  如果我们的操作比较简单,我们可以在这个函数中直接完成,在测试时比骄傲方便,在复杂一点的应用中不建议这么做。在这里我们实现这个函数如下:

/* USB应用处理回调函数 */
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{switch(id){case HOST_USER_SELECT_CONFIGURATION:
​    break;
​    case HOST_USER_DISCONNECTION:
​    Appli_state = APPLICATION_DISCONNECT;
​    break;
​    case HOST_USER_CLASS_ACTIVE:
​    Appli_state = APPLICATION_READY;
​    break;
​    case HOST_USER_CONNECTION:
​    Appli_state = APPLICATION_START;
​    break;
​    default:
​    break;}
}

  我们还需要轮询USBH_Process函数并处理我们的应用任务,如读写文件操作等。我们在这一函数中,先调用USBH_Process函数,然后根据当前的状态来决定应处理的工作。在这里,我们希望在USB检测到U盘准备好后对齐进行读写操作,所以我们实现如下:

/* USB通讯数据处理 */
void McUsbDataProcess(void)
{/* USB 主机过程:应在主循环中调用,运行主机协议栈 */USBH_Process(&hUsbHostFS);switch(Appli_state){case APPLICATION_START:
​    {​      break;
​    }case APPLICATION_READY:
​    {​      MSC_Application();
​      Appli_state = APPLICATION_IDLE;
​      break;
​    }case APPLICATION_DISCONNECT:
​    {​      break;
​    }case APPLICATION_IDLE:
​    {​      break;
​    }default:
​    {​      break;
​    }}
}

  我们实现USB主机库的移植,我们尝试往U盘写一个名为STM32.txt的文件,经测试是成功的,具体如下图:

  上图中,我们创建了一个名为STM32.txt的文本文件,我们进一步像文件中写入一定的字符。我们写入一句话,其结果如下:

  至此,我们可以确定我们的USB主机库移植及大容量存储设备的操作应该是正确的。

4、小结

  在usbh_conf.c和usbh_conf.h文件的实现中已经将硬件接口对象HCD_HandleTypeDef已经连接到了USB主机对象USBH_HandleTypeDef上,所以在应用层面就需要操作USBH_HandleTypeDef对象了。

  在移植测试过程中,我们发现了一个现象。如果在USB HOST库完成软硬件初始化之前就插入U盘,则系统不能完成初始化。等到初始化完成之后插入U盘则操作正常。

欢迎关注:

USB应用开发笔记之一:STM32上实现USB主机读写U盘相关推荐

  1. Linux USB 驱动开发实例(七)—— 基于USB 总线的无线网卡浅析

    回顾一下USB的相关知识 USB(Universal Serial Bus)总线又叫通用串行外部总线, 它是20世纪90年代发展起来的.USB接口现在得到了广泛的应用和普及,现在的PC机中都带有大量的 ...

  2. iTOP-RK3568开发板Android11系统开发笔记使用ADB工具允许usb调试

    1 使用 ADB 工具 ADB 英文名叫 Android debug bridge ,是 Android SDK 里面的一个工具,用这个工具可以 操作管理 Android 模拟器或者真实的 Andro ...

  3. Linux USB 驱动开发实例 (三)—— 基于USB总线的无线网卡浅析

    回顾一下USB的相关知识   USB(Universal Serial Bus)总线又叫通用串行外部总线,它是20世纪90年代发展起来的.USB接口现在得到了广泛的应用和普及,现在的PC机中都带有大量 ...

  4. android usb单反相机,在Android应用程序上使用USB Camera

    只有当USB相机中的传感器符合UVC标准(今天的大多数相机都符合)时,讨论才成立. 默认情况下,没有Android API可用于外部摄像头.所以如果你对这个项目很认真,那么你所做的工作就是编写一个与内 ...

  5. 【ARM-Linux开发】Rico Board上编译USB WiFi RT3070驱动

    1.附件中提供了RT3070驱动源码包DPO_RT5572_LinuxSTA_2.6.1.3_20121022.tar.gz和编译好的驱动,这里选择使用taget_file.tar.gz中已经编译好的 ...

  6. linux禁用usb的命令,禁用Linux机器上的USB存储设备

    方法1–伪安装 在本方法中,我们往配置文件中添加一行installusb-storage/bin/true,这会让安装usb-storage模块的操作实际上变成运行/bin/true,这也是为什么这种 ...

  7. IOS开发笔记之十七——一个关于工程目录读写权限的问题

    1.从互联网上或者其他途径拿过来的工程代码,往往会报下面的提示: (1)打开文件的时候出现窗口提示You don't have permission to save the file "pr ...

  8. stm32如何读取并口_CH374T STM32模拟并口总线读写U盘

    | |-- ARM32: 32位指令ARM单片机 | | |-- LIB9: U盘文件级子程序库,ADS V1.2,小端数据格式 | | | |-- EXAM1: C示例源程序,查询方式 | | | ...

  9. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

最新文章

  1. FileNotFoundError: [Errno 2] No such file or directory: _MEI138162\\astor\\VERSION‘
  2. 智源青年科学家黄高:面向高效推理的深度网络结构设计
  3. dom定位的三种元素
  4. is_sorted() 函数---一个判断数组和容器是否有序的函数
  5. MongoDB管理:慎用local、admin数据库
  6. “返回指向栈空间的指针”的错误
  7. 开源供应链金融_成为开源供应链
  8. Registry:THERE IS NOT VERSION ASSOCIATED FOR THIS PARTICULAR SCHEMA
  9. 重大发现: windows下C++ UI库 UI神器-SOUI(转载)
  10. 去除移动端alert/confirm的网址(url)
  11. 数据结构笔记-----树
  12. sqlmap安装(python2或python3都行)
  13. android 设备实现定时重启(无root权限或已root)
  14. [oracle] Instant Client 即时客户端
  15. python遥感数据有偿处理_地质男转行学遥感Python——DMSP数据预处理二
  16. xy苹果助手安装_xy苹果助手
  17. 以天下之力成天下之事,菜鸟成物流抗疫主力军
  18. java ireport 打印_ireport客户端打印
  19. PCL报错:C2248 “pcl::Registration<PointSource,PointTarget,Scalar>::setInputCloud”
  20. 【XSY2538】/【HDU6155】Subsequence Count(矩阵乘法+线段树)

热门文章

  1. 知识图谱之语言计算与信息抽取
  2. 034 Android NavigationView和DrawerLayout实现抽屉式导航设计(侧边栏效果)
  3. Codeforces Round #462 (Div. 2), problem: (C) A Twisty Movement (求可以转一次区间的不递增子序列元素只有1,2)...
  4. CONTINUE...? ZOJ - 4033
  5. 前端开发神器 vscode 常用快捷键
  6. Android高德地图自定义Markers的例子
  7. 将JSON转成DataSet(DataTable)
  8. Finding Gems
  9. 3.1_ 6_ 基本分页存储管理的基本概念
  10. 【剑指offer】面试题6:从尾到头打印链表(Java)