USB(Universal Serial Bus)是一种支持热插拔的通用串行总线。它使用差分信号来传输数据,在 USB 1.0和 USB 1.1 版本中,只支持 1.5Mb/s 的低速(low-speed)模式和 12Mb/s 的全速(full-speed)模式,在 USB 2.0 中,又加入了480Mb/s 的高速模式,USB 3.0(super speed),传输速率最大5Gbps。, l- v3 I7 g" w7 c: x& X 在 USB 体系中又包括 USB Host(主机)和USB Device(设备)USB Host任何USB系统中只有一个主机。主机系统的USB接口被称为主机控制器。主机控制器可以以硬件,固件或软件的组合来实现。根集线器集成在主机系统内以提供一个或多个连接点。USB Device 可以分为 USB Hub 和 USB FunctionUSB Hub 提供了一种低成本、低复杂度的 USB接口扩展方法。Hub 的上行端口面向 HOST,下行端口面向设备(Hub 或功能设备)。在下行端口上,Hub 提供了设备连接检测和设备移除检测的能力,并给各下行端口供电。Hub 可以单独使能各下行端口。不同端口可以工作在不同的速度等级(高速/全速/低速)。USB Function 能够通过总线传输或接收数据或控制信息的设备,在 USB2.0 标准中,别称为 Class 本文主要是基于正点原子 stm32f767-atk-apollo 开发板,给出了 USB Host 读写 U 盘的配置和使用示例。本文准备资料如下:
6 H6 h, a# r1 V, @; Z% g* n+ o, v+ L 依赖
* L% R; t# _# z. ]# U8 ~2 w8 K% D 硬件连接准备本文是基于 U 盘的读写,所以需要准备好一个 U 盘,并插入开发板上的 U 盘接口。 ENV 配置打开 USB Host: N3 S/ L" \. a- J2 u/ H- s; B' k RT-Thread 可以很方便的通过 ENV 来配置和生成工程。在 rt-thread\bsp\stm32\stm32f767-atk-apollo 目录下打开 ENV 工具,使用 menuconfig 进入如下配置界面并选中。 1---- Hardware Drivers Config2 ----On-Chip Peripheral Drivers 3 ----Enable USH Host6 U) R2 c9 n3 L* q 4 ----Enable Udisk Drivers- n! |% n% {4 L% ]1 ~( Q( b 配置界面如下图所示
本文使用的是 USB Host 读写 U 盘的功能,所以需要打开 RT-Thread 的虚拟文件系统功能,打开文件系统的操作如下 1---- RT-Thread Components2 ----Device virtual file system: x# ]. [" ^4 r5 N1 @ 3 ----Using device virtual file system5 S% o7 S# V& i& \& v! m& {; H 配置界面如下图所示
在 ENV 中打开 USB Host 和虚拟文件系统的功能之后,工程配置就结束了,退出配置界面并保存。在 ENV 工具中使用 scons --target=mdk5 命令重新生成工程并打开。工程打开之后可以看到 USB Host 的框架代码和驱动代码都已经自动加入到工程里面了,如下图所示
在 main.c 文件中加入以下测试代码并下载 (向右滑动查看全部代码) 2#define TEST_FN "/test_usbh.c"- p2 ~0 G5 }0 u( S/ N0 ?$ F7 o# Z 3static char test_data[120], buffer[120]; 4, N! ?/ z5 c; R0 I7 m% A 5void readwrite(const char* filename) 6{# u8 h/ W5 w7 C1 j) ^( x, n1 d 7 int fd; 8 int index, length;# Q. h; ~0 Z# n: I+ c4 o4 s 9 10 fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);4 K! J8 z j# B# q0 T2 ~, c 11 if (fd < 0) 12 { 13 rt_kprintf("open file for write failed\n"); 14 return;8 T' G2 [8 t8 H+ L$ w 15 }6 q9 C6 ]4 |# U% G 167 W k$ ]4 M: e) A" a 17 for (index = 0; index < sizeof(test_data); index ++) 18 { 19 test_data[index] = index + 27;# C! E b% O; _# G9 T! u 20 } 21) S+ s& m6 q" y7 l9 p 22 length = write(fd, test_data, sizeof(test_data));! A, d7 P/ [* X! G/ h; [ 23 if (length != sizeof(test_data))/ S. {/ I/ q. Q( s4 N, S 24 {7 g! e3 I5 i4 v" h 25 rt_kprintf("write data failed\n");/ e4 {8 @& A" @# w) \$ c2 i 26 close(fd); 27 return; 28 } 29# I! E9 h: w. ^# f( D- L8 R) Z 30 close(fd); 31 32 fd = open(TEST_FN, O_RDONLY, 0); 33 if (fd < 0)1 G" a$ t, T9 h. [* d( G$ K 34 {7 j' L0 `! q: Q3 e( h 35 rt_kprintf("check: open file for read failed\n");( Q( h% {: x: G. M# X0 ~- X 36 return; 37 } 38; V! `' `2 A0 s: K$ { 39 length = read(fd, buffer, sizeof(buffer));/ `& @9 s* D4 z" S 40 if (length != sizeof(buffer)) 41 { 42 rt_kprintf("check: read file failed\n"); 43 close(fd); 44 return; 45 } 460 N. S$ m+ c. i* a6 Q 47 for (index = 0; index < sizeof(test_data); index ++) 48 {: `$ s0 G$ {8 S1 Q( ?& W 49 if (test_data[index] != buffer[index])4 \/ A+ i3 \- @9 w4 V/ y 50 { 51 rt_kprintf("check: check data failed at %d\n", index); 52 close(fd);3 f2 b8 i' _- J( Y 53 return;2 Z6 F2 o2 E7 c( y6 D 54 }+ ^0 Y4 c3 j2 x5 y$ D- N8 v7 H! l 55 }( B% @2 D+ u, Z, K* _( y: Q! G 56 57 rt_kprintf("usb host read/write udisk successful\r\n"); 58 59 close(fd);9 }- r i# V/ M) j 60} 61% z5 m6 }, t+ P5 N; M 62MSH_CMD_EXPORT(readwrite, usb host read write test);$ o3 Z* e L" P# | 运行测试程序3 X4 F: ^8 ^/ U& C 将以上程序下载入开发板之后连接串口调试工具可以看到如下调试信息
这里可以看到 U 盘的大小约为 7.4G,说明 U 盘已经成功挂载到开发板上面的文件系统了。使用文件系统的 ls 命令查看 U 盘目录的结果如下图:
|
最全USB HID开发资料,悉心整理一个月,亲自测试
USB Audio设计与实现
【MCU实战经验】+STM32F107的USB使用
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32 USB-HID通信移植步骤STM32 USB HID键盘例程
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
如何让CDC类USB设备批量接收64字节以上数据
用STM32F4实现的USB摄像头UVC,配合上位机可识别车牌
STM32 USB CDC 虚拟多串口