USB

AT32 USB主机协议库

这部分主要介绍AT32 USB主机库的结构和库的使用方法,AT32 USB支持全速和低速,不支持USB2.0高速设备。这里库的作用是用来管理USB外设和实现USB的基本协议,使开发者能够更快的上手开发。

USB主机库包含以下几个模块 如图1:

  • 用户应用程序

此部分为开发者根据应用具体需求开发应用程序。

  • USB Core Driver和USB主机类

USB Core Driver:此部分实现USB设备标准协议栈,标准请求等接口。

USB主机类:此部分实现具体USB主机请求。

  • USB主机硬件底层接口

此部分实现硬件寄存器抽象接口

  • USB/OTG外设

1.png

图1. USB主机库结构

AT32 USB库文件

如下是AT32 USB应用工程结构图:

2.png

图2. AT32工程结构

Core Driver库路径:OTGFS-->middlewares\usb_drivers

Host Class库路径:middlewares\usbh_class

如下是USB主机库文件列表:

3.png

表1. USB主机库文件列表

4.png

表2. USB主机类文件列表

USB主机库文件说明

USB库实现USB主机枚举标准请求,同时实现USB规格里面的4种传输类型(control,interrupt,bulk,isochronous)的函数接口。

5.png

图3 USB主机库文件结构

USB主机文件函数接口

usbh_int.c函数接口

usbh_int.c主要处理底层中断,包括设备连接,设备断开等。

6.png

表3 usbh_int函数接口

usbh_core.c函数接口

usbh_core.c此文件封装不同的usb主机函数接口用于不同的地方调用,包括一些接收,发送函数等。

7.png

表4 usbh_core函数接口

usbh_ctrl.c函数接口

usbh_ctrl.c此文件处理USB主机枚举过程中的一些标准请求。

8.png

表5 usbh_ctrl函数接口

支持的标准设备请求如下表:

9.png

表6 标准设备请求

usbh_xx_class.c函数接口

usbh_xx_class.c此文件为具体主机类型的数据处理,通过结构体函数来实现不同主机类型数据的处理。开发者根据不同的主机类型,来实现下面函数结构体中的函数,达到不同应用结果。

函数结构体如下:

10.png

表7 主机class函数结构体

11.png

表8 主机class函数接口

usbh_user.c函数接口

usbh_user.c此文件主要为一些给用户处理事件的函数如复位,断开连接等。

12.png

表9 用户事件函数结构体

13.png

表10 用户函数接口函数

其它参数函数

的参数结构体如下,USB主机库中参数传递使用结构体usbh_core_type,如下图:

14.png

图4 全局结构体

USB主机的状态机如下图:

15.png

图5 USB主机状态机

USB返回值,USB函数接口使用如下函数返回值。

16.png

图6 函数返回值

通道FIFO分配

USB主机要正常收发数据,在初始化时需要为通道分配FIFO,分配给所有通道FIFO大小的和不能超过系统分配给USB缓冲区的最大长度,具体USB的缓冲区大小参考RM上的描述。

开发者可以参考例程usb_conf.h为通道自定义分配FIFO。
OTGFS主机通道FIFO分配

主机模式下,所有通道共享一个接收FIFO,通道发送FIFO分为非周期性发送FIFO和周期性发送FIFO。注意usb_conf.h中对端点分配的FIFO大小单位为word(Byte)。

以hid_demo例程为例:

17.png

USB主机初始化

在使用USB主机功能时,需要对USB的寄存器做一些基本的初始化,通过调用USB主机的初始化函数完成这部分的操作。
OTGFS外设初始化

OTGFS初始化函数usbd_init包含5个参数:

18.png

例程主机hid_demo的初始化如下:

19.png

USB主机中断处理

USB主机中断入口函数usbh_irq_handler处理所有USB主机中断,包括连接状态,通道收发数据,SOF,唤醒等中断,下面介绍一些典型的中断处理。

20.png

图7 USB主机中断处理函数

通道中断处理

当USB主机与设备进行通信时,通道的收发状态都在通道中断中处理,通道的方向分为IN和OUT通过通道寄存器中的方向为进行判断。

中断处理函数:usbh_hch_handler

代码如下:

21.png

Wakeup 中断处理

当USB主机在挂起状态时,检测到设备触发的远程唤醒信号,将产生此中断。此中断会将当前主机状态改为WAKEUP状态:

中断处理函数:usbh_wakeup_handler

代码如下:

22.png

接收FIFO非空中断

此中断表示当前接收FIFO有数据,应用程序通过此中断读出接收到的数据,并存放到对应通道的FIFO当中,当数据读取完成之后,会产生对应的通道的中断。

中断处理函数:usbh_rx_qlvl_handler

代码如下:

23.png

主机端口中断处理

当USB主机断开发生状态改变时,会产生端口中断,应用程序通过此中断判断连接设备的速度等。

中断处理函数:usbh_port_handler

24.png

设备断开连接中断处理

当连接的设备断开是,会产生断开连接中断。

中断处理函数:usbh_disconnect_handler

代码:

25.png

USB主机枚举处理

USB主机状态机在usbh_loop_handler函数中处理,对应的主机状态机uhost->global_state,如下图是设备连接到主机的状态处理流程:

26.png

图8 设备连接状态机流程

  • USBH_IDLE:当USB启动或者设备断开连接之后在此状态

  • USBH_PORT_EN:USB主机端口使能之后在此状态

  • USBH_ATTACHED:USB设备连接稳定之后

  • USBH_ENUMERATION:USB设备标准的枚举流程

  • USBH_USER_HANDLER:枚举完成之后,调用主机类的初始化函数

  • USBH_CLASS_REQUEST:主机类初始化完成之后,进行主机类请求

  • USBH_CLASS:所有枚举完成,进行正常的数据处理。

USB主机枚举流程

当设备接到主机之后,通过控制端点(端点0)进行枚举动作,USB主机的枚举状态如下:

27.png

如下是主机枚举的状态机流程:

28.png

图9 USB主机枚举流程

  • ENUM_GET_MIN_DESC:获取8字节设备描述

  • ENUM_GET_FULL_DESC:获取18字节设备描述

  • ENUM_SET_ADDR:设置设备地址

  • ENUM_GET_CFG:获取9字节配置描述

  • ENUM_GET_FULL_CFG:获取完整的配置描述

  • ENUM_GET_MFC_STRING:获取设备厂商信息

  • ENUM_GET_PRODUCT_STRING:获取设备产品信息

  • ENUM_GET_SERIALNUM_STRING:获取设备序列号信息

  • ENUM_SET_CONFIG:SET CONFIGUREENUM_COMPLETE:枚举完成

USB控制传输过程包含SETUP-DATA-STATUS三个阶段,如下是一个主机获取设备信息的传输过程GET_DESCRIPTOR:

29.png

图10 Get Descriptor

如下是USB主机库一个SETUP-DATA-STATUS函数调用流程:

30.png

图11 USB主机SETUP函数调用

usbh_ctrl_transfer_loop函数中断对控制请求的各个状态阶段进行处理:

控制请求状态机:

31.png


32.png

图12 控制请求处理流程

USB主机类初始化

在USB标准枚举完成之后,会调用USB主机类的初始化,在初始化函数中解析当前枚举的设备是否支持,调用函数uhost->class_handler->init_handler(uhost)。

初始化代码例:

33.png

USB主机类请求

USB主机类初始化之后,可以发送主机类控制请求,根据不同的设备类,需要实现不同的设备类请求。调用函数uhost->class_handler->request_handler((void*)uhost);

主机类请求例:

34.png

USB主机数据处理

所有枚举完成之后,将进行主机数据处理

主机数据处理例:

35.png

USB主机类型例程

本章将说明使用AT32 USB主机库实现不同的主机类型的例程。目前实现的主机类例程如下:

  • hid(mouse,keyboard)

  • mass storage(msc_only_fat32)

  • two_otg_host_demo(仅AT32F435/437支持)

HID例程

HID类支持鼠标和键盘设备,开发者可修改此例程用以实现支持其它HID类设备。

HID类:

36.png

HID类例程初始化

当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler, 调用此函数将解析接到主机上的设备类型,是鼠标还是键盘或者其它设备。通

过设备的配置描述信息进行如下流程解析:

  • 查找HID接口

  • 判断接口是鼠标还是键盘

  • 查找对应接口的端点号

  • 初始化对应通道

代码如下:

37.png

HID类请求

HID类请求实现一些HID设备的标准请求,调用函数uhost_request_handler

  • SET_IDLE

  • SET_PROTOCOL

  • GET_REPORT

代码如下:

38.png

HID类数据处理

HID枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。

  • 通过usbh_interrupt_recv函数给设备发送IN请求

  • 通过usbh_get_urb_status(puhost, phid->chin); 获取IN请求的状态

  • 通过phid->in_poll判断多长时间发送一次IN请求

  • 通过phid->protocol判断是鼠标还是键盘

代码如下:

39.png

MSC例程

msc_only_fat32实现一个简单的mass storage主机类,仅支持FAT32格式。

MSC类:

40.png

MSC 类初始化当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler,调用此函数将解析接到主机上的设备类型,判断是否是MSC类型。

通过设备的配置描述信息进行如下流程解析:

  • 查找MSC接口

  • 查找对应接口的端点号

  • 初始化对应通道

  • 初始化bulk-only和SCSI状态机

代码如下:

41.png

MSC类请求

MSC类请求实现一些MSC设备的标准请求,调用函数uhost_request_handler

  • GET_MAX_LUN

代码如下:

42.png

MSC类数据处理

HID枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。

实现如下命令:

  • INQUIRY

  • TEST_UNIT_READY

  • READ_CAPACITY10

  • REQUEST_SENSE

代码如下:

43.png

MSC读写数据

MSC读写数据在通过FATFS接口进行实现,在usbh_msc_diskio.c中实现读写函数。

读函数:

44.png

写函数:

45.png

CDC例程

cdc实现一个简单的虚拟串口类。

CDC类:

46.png

CDC类例程初始化

当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler, 调用此函数将解析接到主机上的设备类型。

通过设备的配置描述信息进行如下流程解析:

  • 查找CDC接口

  • 判断接口是否为虚拟串口

  • 查找对应接口的端点号

  • 初始化对应通道

代码如下:

47.png

CDC类请求

CDC类请求实现一些CDC设备的标准请求,调用函数uhost_request_handler

  • GET_LINECODING

代码如下:

48.png

CDC类数据处理

CDC枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。

  • 通过set_linecoding和get_linecoding配置linecoding

  • 通过cdc_process_reception(puhost)函数给设备发送IN请求

  • 通过cdc_process_transmission(puhost)函数发送数据给设备

代码如下:

49.png

two_otg_host_demo例程

AT32F435/437存在两个OTGFS,此例程说明同时使用两个OTGFS实现两个host功能。

  • 实现功能:

  • OTGFS1实现MSC主机(参考MSC例程)

  • OTGFS2实现HID主机(参考HID例程)

配置与实现

在usb_conf.h中配置OTGFS1和OTGFS2:

50.png

在main中初始化:

51.png

来源:AT32 MCU 雅特力科技

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 16

传统设备数据传送依靠有线USB将信息传输至主机,经常面临多条线材摆放凌乱、布线空间及操控范围受限等问题。基于科技革新速度不断加快、技术推陈出新,IoT概念普及化,多数设备已由有线逐渐转变为无线。

雅特力超值型AT32F415与无线型AT32WB415系列采用强大的32-bit ARM® Cortex®-M4内核,在SoC单芯片系统上,整合多种通讯接口,如USB OTG、UART、SPI、I2C、SDIO等,搭配RF射频进行信息传输,实现USB HID无线传输功能,无须额外安装驱动程序,即可帮助用户快速完成信息传送和保持文件完整性。本文将以客户实际应用案例「血压计导入AT32F415/AT32WB415系列MCU连接USB HID应用」为例,介绍AT32 MCU在USB HID上的应用。

AT32 MCU提供一个高精度、高性价比的血压计应用解决方案,当血压计测量脉搏率、收缩压和舒张压时,压力传感器精确检测到血压信号强度,如下图所示。

血压计量测信息传送情境对照图:

“导入AT32
导入AT32 MCU搭配RF射频实现无线传输

AT32F415 / AT32WB415系列连接USB HID应用方案特点

  • 采用ARM® Cortex®-M4内核,主频高达150MHz,内建大容量256KB Flash和32KB SRAM,并提供软件开发工具,以便进行产品系统校正、更新和储存用户信息。

  • 支持UART、SPI、 I2C 、SDIO、USB OTG、CAN多种通讯界面,同时搭配RF无线射频组件,支持蓝牙无线传输功能(适用AT32WB415系列方案二),实现智能应用与产品功能价值。

AT32F415 / AT32WB415系列导入血压计产品附加优势

  • 支持12位高精度ADC及CMP,从压力传感器采集信号中分辨袖带和脉搏波信号,精准提取脉搏波信号,经滤波电路后,透过A/D转换电路,输出至CPU,无须添加额外组件,大幅降低开发成本和缩短量产时程。

  • 支持高速GPIO/SPI驱阿动LCD显示屏,流畅显示血压量测读值状态。

  • 支持蓝牙2.4GHz频段,Rx灵敏度可达到-97dBm,Tx值介于-20dBm~+4dBm之间,有效传输范围超过30m,数据传输最快可达到2Mbps,实现无线传输低延迟(适用AT32WB415系列方案二)。

“AT32

更多参考文件信息,详见雅特力官网:
https://www.arterychip.com/en/product/AT32WB415.jsp

来源:AT32 MCU 雅特力科技
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 17

问题描述

客户反馈,使用STM32F446的高速USB外设,即USB_OTG_HS外设,且使用内置全速PHY。客户的产品USB用做device,自定义HID类,当连接带UOS操作系统的HOST时,会发现当前数据并没有成功发送,但是会发送上一次的数据,即发送数据出现”迟滞”现象。但在Windows下却没有出现此类问题。另外,客户同时还使用了STM32F446上的USB_OTG_FS外设,且此外设做同样的事一切正常,目前此问题只出现在USB_OTG_HS外设上。

问题查找

刚开始猜测是长度问题,即发送最大包长需要再发送一次空包。但客户反馈他们的发送长度为62个字节。于是去客户现场使用USB协议分析仪采数分析,发现一切通信正常。

通过查看客户演示重现问题的过程,发现在正常时是一切OK的,只在进行USB拔插时才发送问题。应用程序不断发送数据的过程中拔掉USB线,然后再次插上,在此过程中应用程序一直尝试发送数据。当USB线重新连接上且重新枚举成功后,“迟滞”现象则重现了,即每次应用程序调用发送接口实现发送的是上一次尝试发送的内容。

调试客户的程序,发现当USB线拔掉后,应用程序还会往USB IP对应的发送FIFO内写入数据,这其实是不对的。按理USB线拔掉后USB的状态应该恢复到默认状态,

即pdev->dev_state=USBD_STATE_DEFAULT. 但实际上,通过调试发现此状态在USB线拔掉后是suspend状态。

那么为什么会是这样的呢?

于是立即想到Vbus sensing功能。马上与客户硬件工程师核对,原来客户产品的USB_OTG_HS的Vbus_sensing脚是悬空的,并没有连接Vbus,但是客户的USB_OTG_FS外设却又是连接了。于是客户的产品两个USB口,同样的工作,一个USB口 正常,另一个USB口却会出现问题。

问题分析

差异找到了,接下来就是分析由此如何造成问题的。

由于USB_OTG_HS并没有真正实现Vbus sensing功能(因为没有硬件连接),于是当USB线断开时,应用程序并不能准确地检测到断开事件(Disconnected),只会出现suspend,应用程序是无法直接的区分真正的suspend和USB线断开连接的。当应用程序有数据需要通过USB口发送时,如果当前是suspend状态,那么它会首先唤醒USB总线然后再发送数据:

“USB发送数据时出现迟滞现象"
Figure1

而这样发送远程唤醒信号时,device本身会产生一个resume中断,于是在resume中断回调函数内:

“USB发送数据时出现迟滞现象"
Figure 2

如上所示,程序会将dev_state错误地恢复到上一次状态,即正常状态USBD_STATE_CONFIGURED, 如此一来,程序就错误地往USB IP的内的发送FIFO写入数据了,即使此时由于USB线已经断开而导致无法真正发送成功,但USB IP的内置发送FIFO此时是有了数据的。

通过调试,查看OTG_DTXFSTS1寄存器相应端点1对应的发送FIFO的剩余空间可知,这个时候的发送FIFO的确实有数据的。接下来是USB线插上重新枚举,那么为什么USB重新枚举后还会再现问题呢?通过设置断点发现,在USB成功重新枚举过后,通过OTG_DTXFSTS1寄存器指示,发送FIFO内容并没有清空,于是在接下来发送数据时,永远都是实际上发送的是上一次写入到FIFO中的数据。

问题解决

▼于是解决方法就很容易找到了▼

在USB重新枚举过后在合适的地方将端点1对应的发送FIFO清空一下即可。

“USB发送数据时出现迟滞现象"
Figure 3

问题总结

在客户的这个案子中,由于USB_OTG_FS连接了VBUS SENSING脚,当USB线拔掉后,会产生正确的disconnect中断,USB device的状态也会正确地切换到default状态,从而过滤掉应用程序想要发送的数据,因此并不会出现类似问题,因此,在客户的产品设计中,建议硬件千万不要忘了连接vbus引脚,即使在想省IO引脚的情况下,这样容易造成对软件的开发诸多不便.

在USB的状态处于非configured状态时,最好不要往发送FIFO写入数据,应用程序应该想办法将这些数据过滤掉。

来源:STM32单片机
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 21

引言

本文介绍了如何使用MCUXpresso Config Tools来快速生成一个可用的USB composite device的demo,以便节省时间直接进行USB应用层的开发,而不必关注USB协议栈及底层的配置。

文详细介绍了如何利用Config Tools生成USB Composite Device工程的全部步骤,并且还会介绍,如何将这些代码porting到IAR等不同IDE中进行开发。

组合设备介绍

USB的composite类是指在一个USB设备中,实现多个不同功能的特殊USB类,如一个设备实现鼠标加键盘或者U盘加键盘的功能。

实际上,USB composite类几乎可以将任意的USB功能进行组合,并且组合的数量也不局限于两个,只要端点资源够多,可以组合三个或多个功能于一个设备上。

在USB中,还存在有一种compound device的概念,它与composite device都可以译作复合设备或组合设备,但是它们是两个完全不同的概念。

USB compound device(USB复合设备)中内嵌Hub和多个功能,每个功能都是独立的USB设备,有独立的VID与PID,从实现层面上讲就是一个物理设备实现了一个Hub和多个物理设备。

USB composite device(USB组合设备)中只有一套VID与PID,通过不同的接口将这同一个设备定义为不同的功能的组合。而不同功能的实现依赖于不同的类接口的合并。

环境搭建

本文使用i.MX RT1060-EVK板作为演示对象,所使用的MCUXpresso IDE(以下简称MCUX)版本为v11.4.0,其中内置了v10.0.0版本的Config Tools,使用内置的Config Tools所生成的工程,可以直接在MCUXpresso IDE内编译下载,下一章将会介绍如何将生成的代码集成到IAR中进行编译下载运行。

在使用MCUXpresso生成工程时需要加载SDK到MCUXpresso环境中,本文使用的SDK版本为2.10.0。

以下例子是生成了一个包含CDC VCOM、MSC、HID Mouse三个类功能的组合设备。

配置工程

首先需要创建工程。

进入MCUXpresso IDE界面后,点击New project进入创建工程界面,选择evkmimxrt1060板,点击next,进入config界面,点击middleware选项卡,选中USB Device和USB PHY选项, USB Common Header会被自动勾选,最后点击Finish完成工程创建。

具体步骤如下图:

“手把手带您使用MCUXpresso

完成工程的创建后,选择ConfigTools选项卡下的Peripherals,进入工程配置界面,在左侧Components窗口下,点击Middleware右侧的加号,弹出选择界面,在选择界面中选中USB,点击OK。操作步骤如下图所示。

“手把手带您使用MCUXpresso

此时,我们已经将USB中间件添加进入配置,刚添加进入后会发现右下角的Problems界面内会报两条错误,为了解决其中的时钟错误,首先还是在ConfigTools选项卡内,选择Clocks,进入Clock配置界面,选择Clock Outputs界面中的USBPHY1 PLLclock,然后在右侧的Details界面内Enable USBPHY1 clock output,具体步骤如下图所示。

“手把手带您使用MCUXpresso

返回Peripherals界面,时钟的错误已经消除,下面开始添加USB的功能接口,在刚才添加的USB1的主界面内根据自己的需求修改device的VID及PID。

点击Supported interfaces选项旁边的加号,添加一个interface,会生成一个interface0,默认新添加的interface的类都是DFU,在右侧Class下拉菜单中选择想要实现的组合设备中的第一个类。此处需要注意的是,CDC VCOM的实现需要用到两个子类interface,分别是用于管理和控制的通信类接口CIC与用于传输数据的数据接口类DIC,在Config Tools中需要分别添加两个interface组成来一个CDC VCOM的功能。

添加两个interfaces,分别设置类为CIC VCOM及DIC VCOM。Config Tools添加interfaces时,是按照顺序使用端点号及interface号,这里我们不修改任何参数,直接使用默认的数据,如果应用层有特殊需要的,也可以修改端点的相关参数来满足需求。

第一个CDC VCOM类的功能添加完成后,开始添加第二个MSC类的interface,仍然是点击加号,修改Class为MSC,其余的配置都保持默认。

最后进行HID类的配置,仍然是点击加号,添加新的interface,修改Class为HID,在右侧的Present下拉框内选择Mouse,需要使用自定义HID报告的应用可以选择None,并且自己进行Endpoints和report的配置。

所有配置过程如下图所示:

“手把手带您使用MCUXpresso

在所有类的interfaces添加完成后,点击上方菜单中的UpdateCode,在弹出的对话框中,可以看到本次配置对哪些文件产生了影响,此处需要注意的是,需要前两个board文件夹下的4个文件的默认勾选去除掉,然后点击OK,完成代码的生成。

具体步骤如下图所示。

“手把手带您使用MCUXpresso

在生成完成代码后,MCUX会自动跳转回工程开发界面,打开source目录下的与工程同名的.c文件,在头文件处添加’ #include "usb_device_composite.h"’,并且将主循环里的内容替换为USB_DeviceTasks();。

修改的步骤如下图所示。

“手把手带您使用MCUXpresso

完成上述修改后即可编译下载到RT1060-EVK板上进行测试。下载完成后按下EVK板的reset键,连接USB1口到PC的USB口,打开设备管理器可以看到生成了一个新的composite device,并且同时,还可以在各个设备类下面查找到实现的相应的设备,并且这些设备的PID\VID相同,都是在配置界面内所配置的PID\VID,如下图所示。

“手把手带您使用MCUXpresso

移植到IAR环境

先要准备一个IAR的工程。

在SDK生成器中下载一个带有完整的USB stack的SDK包,然后在同样的页面内下载一个Standalone的示例工程,如下图所示。

“手把手带您使用MCUXpresso

根据所要生成的Composite Device所含的类的种类,选择SDK中的某单一类的工程,例如,本应用笔记中的Composite Device包含了三个类,在生成单独的工程时,选择dev_hid_mouse_bm的工程。

接下来需要添加和删除一些文件

上一节中生成的工程中,只包含了HID类的相关文件,所以我们需要朝工程内添加两部分的文件,以实现composite device的功能。

第一部分的文件是USB stack相关的文件,这也是为什么我们需要一个完整的SDK包的原因,从SDK包的middleware\usb\output\source\device\class\目录中将MSC类及CDC类相关的文件添加到工程中。如下图所示。

“手把手带您使用MCUXpresso

第二部分文件是由Config Tools生成的文件,这部分文件在MCUX的工程目录下能够找到,将Config Tools生成的文件复制到IAR工程目录下,并且如下图所示将它们添加进工程。

“手把手带您使用MCUXpresso

在完成文件的添加后还需要把原本source目录下的文件从工程中去除,以免除本来工程里的文件与工具所生成的文件产生的冲突。由于使用的基工程是HID Mouse的demo工程,还需要将usb目录下的dcd目录下的文件从工程中去除,否则工程会报错。

需要注意的是,在把所有的文件添加进工程以后,需要在配置里将保存相应头文件的目录添加到include directories中。

完成上述工作后,即可编译下载,运行效果与前一章的效果一致。

来源:恩智浦MCU加油站
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 383

Holtek推出全新一代5V USB MCU系列微控制器HT32F50343,采用Arm® Cortex®-M0+核心,具备高效能与宽广的工作电压,并集成控制RGB LED灯条专用硬件等特色,适合PC(主板、CPU风扇、游戏显卡、内存等)、游戏周边(电竞键盘、鼠标、耳机等)及各种需求LED灯效与USB的应用领域。

HOLTEK推出全新32-bit 5V USB MCU HT32F50343

HT32F50343最高运行速度为60MHz,操作电压为2.5V~5.5V,支持独立VDDIO引脚,提供设计上的弹性。内建64 KB Flash及12 KB SRAM;配备丰富的周边资源,如UART×2、I²C×2、SPI×2、USB、6通道PDMA、12通道1 Msps 12-bit SAR ADC、CRC16/32及硬件除法器等,采用32/46 QFN和48/64 LQFP封装,GPIO引脚可达23~51。

新增的SLED(串列式LED控制器)接口,可搭配DMA同步驱动多达8个灯条。此外还具备PWM Timer×3,SCTM×2和GPTM×1,可输出多达30组PWM信号,满足更广泛的应用。

HT32支持多种开发环境(Keil/IAR/SEGGER/GNU),并提供硬件开发工具包、周边驱动函式库 (Firmware Library)及应用范例等完整的开发资源。全系列M0+ MCU取得Keil MDK-ARM用户许可证,可提供客户免费使用。搭配ISP(In-System Programming)及IAP(In-Application Programming)技术方案,可轻易升级固件。全系列通过UL/IEC 60730-1 Class B认证,可提供自检程序(Safety Test Library)缩短产品认证时间。

来源:HOLTEK

围观 62

转眼间来到了2020年,新年伊始,小编将和大家一起学习使用MM32 MCU的USB功能。对于USB来说,主要应用是HID、CDC、MSC以及WINUSB等功能,此讲先介绍如何使用MM32 MCU的HID功能。

对于USB设备来说,其中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘等,其主要用于人与计算机进行交互。它是USB协议最早支持的一种设备类。HID设备可以作为低速、全速、高速设备用。由于HID设备要求用户输入能得到及时响应,所以其传输方式通常采用中断方式,而且无需安装驱动就能进行交互,简单方便。

在USB通信协议中,HID设备的定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。所以对于某些特定的HID设备,我们可以定义多个接口,只要其中一个接口为HID设备类即可,在学习HID之前,先来复习一下USB协议的相关内容。

一、USB设备描述符-概述

当插入USB设备后,主机需要发送比较短的请求来确认设备的身份、类型、速度等信息,这个过程称之为枚举。

那什么是设备描述符呢?Descriptor即描述符,是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的。

描述符的作用就是通过命令操作作来给主机传递信息,从而让主机知道设备具有什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机确定了这些信息之后,设备才能真正开始工作。

USB有那些标准描述符呢?对于 USB来说有5种标准描述符:设备描述符、配置描述符、字符描述符、接口描述符、端点描述符 。

描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。由此我们可以看出来,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,然后是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。

枚举的过程:

1、等待稳定:主机通过电平差检测到设备,等待100ms让设备电平趋于稳定;

2、首次复位:HUB发起复位,让设备进入初始的地址0模式;

3、首次查询设备描述符:GET_DESCRIPTOR 主机查询设备描述符,只要前8字节 ==> 80 06 01 00 00 00 12 00 ;

4、二次复位:在接收到设备描述符前8个字节后,再次重启设备;

5、设置地址:SET_ADDRESS 主机下发设置地址命令,设备获取新地址 ==> 00 05 01 00 00 00 00 00 ;

6、二次查询设备描述符:GET_DEVICE_DESCRPTOR获取整个18字节的设备描述符 ==> 80 06 01 00 00 00 12 00 ;

7、获取配置描述符:GET_CONFIGURATION 获取9字节配置描述符 ==> 80 06 02 00 00 00 09 00 ;

8、完成配置:SET_CONFIGURATION;

二、HID设备简述

2.1 HID设备的特点

交换的数据储存在称为报表(Report)的结构内,设备的固件必须支持HlD报表的格式。主机通过控制和中断传输中的传送和请求报表来传送和接收数据。报表的格式非常灵活。

每一笔事务可以携带小量或中量的数据。低速设备每一笔事务最大是8B ,全速设备每一笔事务最大是64B,高速设备每一笔事务最大是1024B,一个报表可以使用多笔事务。

设备可以在未预期的时间传送信息给主机,例如键盘的按键或是鼠标的移动。所以主机会定时轮询设备,以取得最新的数据。

HID 设备的最大传输速度有限制。主机可以保证低速的中断端点每10ms 内最多 1笔事务,每一秒最多是 800B,保证全速端点每1ms 一笔事务,每一秒最多是64000B,保证高速端点每125 us 三笔事务,每一秒最多是 24.576MB。

HID 设备没有保证的传输速率。如果设备是设置在 10ms 的时距,事务之间的时间可能等于或小于10ms。除非设备是设置在全速时在每个帧传输数据,或是在高速时在每个微帧传输数据。这个是最快的轮询速率,所以端点可以保证有正确的带宽可供使用。

HID 设备除了传送数据给主机外,它也会从主机接收数据。只要能够符合HlD 类别规范的设备都可以是HID 设备。设备除了HlD 接口之外,它可能同时还包含有其他的USB 接口。

2.2 HID设备的硬件要求

HID 接口必须要符合 Device Class Definition for Human interface Devices 规范内所定义的 HID 类别的需求。在此文件内描述了所需的描述符、传输的频率以及传输的类型等。为了符合规范,HID 接口的端点与描述符都必须符合数个要求。所有的 HID 传输都是使用默认控制管道或是一个中断管道,HID设备必须有一个中断输入端点来传送数据到主机,中断输出端点则不是必需的。Control管道用于接收和响应USB控制和类数据的请求,在由HID类驱动程序轮询时传输数据(使用Get_Reportrequest),从主机接收数据。

对于主机与设备之间所交换的数据,可以分成两种类型:低延迟的数据,必须尽快地到达目的;配置或其他的数据,没有严格时间限制的需求。中断管道是控制管道之外的另一种数据交换的方式,特别适合使用在接收端需要定时或是尽可能及时收到数据的时候。中断输入管道携带数据到主机,中断输出管道则是携带数据到设备。在总线忙的时候,控制管道可能会被延迟,而中断管道保证会有可得到的带宽。HID不需要一定有中断输出管道。如果没有中断输出管道,主机会在控制管道上使用HID 设备特有的 Set_Report 请求来传送所有的报表。

2.3 HID的程序要求

主机的驱动程序要与 HID 设备通信,其设备的固件必须符合如下几个需求,设备的描述符必须识别该设备包含有 HID 接口(描述符)。除了默认控制管道外,固件必须另外支持一个中断输入管道。固件必须包含一个报表描述符来定义要传送与接收的设备数据。如果要传送数据,固件必须支持 Get_Report 控制传输与中断输入传输。如果要接收数据,固件必须支持 Set_Report 控制传输与选择性的中断输出传输。所有的 HID 数据都必须使用定义过的报表格式来定义报表中数据的大小与内容。设备可以支持一个或多个报表。在固件中的一个报表描述符用来描述此报表,以及如何使用报表数据的信息。在每一个报表中的一个数值,定义此报表是一个输入(Input )、输出(Output )或是特征(Feature )报表。主机在输入报表中接收数据,在输出报表中传送数据,特征报表可以在任何方向传递。

三、HID 描述符

HID 设备除了支持 USB 设备的 5 种标准描述符之外,还支持 HID 设备特有的 3 种描述符。这些描述符是:1、USB 标准描述符:设备、配置、接口、端点和字符串描述符;2、HID 特有的描述符: HID 、报表(Report )和实体(Physical )描述符。从描述符的关联关系看, HID 描述符是关联于接口。所以如果一个 HID 设备有 2 个端点,设备不需要每个端点有一个 HID 描述符,具体参考如下代码:

设备描述符

struct _DEVICE_DEscriptOR_STRUCT

{

BYTE   bLength;      //设备描述符的字节数大小

BYTE   bDescriptorType;   //描述符类型编号,为0x01

WORD  bcdUSB;      //USB版本号

BYTE  bDeviceClass;   //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型,0x00不是在设备描述符中定义的,如HID

BYTE   bDeviceSubClass;  //USB分配的子类代码,同上,值由USB规定和分配的,HID设备此值为0

BYTE  bDeviceProtocl;  //USB分配的设备协议代码,同上HID设备此值为0

BYTE   bMaxPacketSize0;  //端点0的最大包的大小

WORD   idVendor;  //厂商编号

WORD   idProduct;  //产品编号

WORD  bcdDevice;  //设备出厂编号

BYTE   iManufacturer;   //描述厂商字符串的索引

BYTE   iProduct;   //描述产品字符串的索引

BYTE   iSerialNumber;  //描述设备序列号字符串的索引

BYTE   bNumConfiguration;   //可能的配置数量

}

配置描述符 

struct _CONFIGURATION_DEscriptOR_STRUCT

{

BYTE  bLength;   //配置描述符的字节数大小

BYTE   bDescriptorType;   //描述符类型编号,为0x02

WORD   wTotalLength;   //配置所返回的所有数量的大小

BYTE   bNumInterface;  //此配置所支持的接口数量

BYTE   bConfigurationVale;   //Set_Configuration命令需要的参数值

BYTE   iConfiguration;  //描述该配置的字符串的索引值

BYTE  bmAttribute;  //供电模式的选择

BYTE   MaxPower;   //设备从总线提取的最大电流

}

字符描述符 

struct _STRING_DEscriptOR_STRUCT

{

BYTE bLength;     //字符串描述符的字节数大小

BYTE bDescriptorType;    //描述符类型编号,为0x03

BYTE SomeDescriptor[36];   //UNICODE编码的字符串

接口描述符

struct _INTERFACE_DEscriptOR_STRUCT

{

BYTE bLength;     //接口描述符的字节数大小

BYTE bDescriptorType;    //描述符类型编号,为0x04

BYTE bInterfaceNunber;    //接口的编号

BYTE bAlternateSetting;   //备用的接口描述符编号

BYTE bNumEndpoints;    //该接口使用端点数,不包括端点0

BYTE bInterfaceClass;    //接口类型 HID设备此值为0x03

BYTE bInterfaceSubClass;   //接口子类型 HID设备此值为0或者1

BYTE bInterfaceProtocol;   //接口所遵循的协议

BYTE iInterface;   //描述该接口的字符串索引值

}

端点描述符

struct _ENDPOIN_DEscriptOR_STRUCT

{

BYTE bLength;     //端点描述符的字节数大小

BYTE bDescriptorType;     //描述符类型编号,为0x05

BYTE bEndpointAddress;    //端点地址及输入输出属性

BYTE bmAttribute;      //端点的传输类型属性

WORD wMaxPacketSize;    //端点收、发的最大包的大小

BYTE bInterval;     //主机查询端点的时间间隔

}

四、MM32 MCU HID代码实现

本次我们采用MM32L373 miniboard作为测试开发板。为了方便大家使用MM32 MCU的HID功能,我们已经封装好全部代码,用户不需要自己配置以上的那些描述符等参数,只需要了解MM32 MCU HID的VID和PID以及如何处理HID的数据接收和发送即可。

软件资源如下:

以下为函数初始化配置及相关全局变量定义内容,代码如下:

#define USBD_POWER                    0

#define USBD_MAX_PACKET0             64

#define USBD_DEVDESC_IDVENDOR      0x2F81

#define USBD_DEVDESC_IDPRODUCT     0x0001

以上是定义的MM32 MCU HID设备VID和PID,灵动微电子已经获得USB组织授权的VID和PID。当设备插入电脑上,可以查看到如上标识的HID设备,如图1所示:


图1 PC设备管理器列表

对于MM32 MCU的HID功能来说,在使用HID功能之前先调用USB初始化函数来初始化USB协议栈。

int main(void)

{

// USB Device Initialization and connect

usbd_init();

usbd_connect(__TRUE);

while (!usbd_configured())   // Wait for USB Device to configure

{

}

while (1)

{      

}

}

 

然后就是HID数据收发处理函数,USB数据处理函数如下:

static volatile uint8_t  USB_ResponseIdle;

static HID_queue HID_Cmd_queue;

 

void hid_send_packet()

{

uint8_t *sbuf;

int slen;

if (HID_queue_get_send_buf(&HID_Cmd_queue, &sbuf, &slen))

{

if (slen > USBD_HID_OUTREPORT_MAX_SZ)

{

util_assert(0);

}

else

{

usbd_hid_get_report_trigger(0, sbuf, USBD_HID_OUTREPORT_MAX_SZ);

}

}

}

 

// USB HID Callback: when system initializes

void usbd_hid_init(void)

{

USB_ResponseIdle = 1;

HID_queue_init(&HID_Cmd_queue);

}

 

// USB HID Callback: when data needs to be prepared for the host

int usbd_hid_get_report(U8 rtype, U8 rid, U8 *buf, U8 req)

{

uint8_t *sbuf;

int slen;

switch (rtype)

{

case HID_REPORT_INPUT:

switch (req)

{

case USBD_HID_REQ_PERIOD_UPDATE:

break;

 

case USBD_HID_REQ_EP_CTRL:

case USBD_HID_REQ_EP_INT:

if (HID_queue_get_send_buf(&HID_Cmd_queue, &sbuf, &slen))

{

if (slen > USBD_HID_OUTREPORT_MAX_SZ)

{

util_assert(0);

}

else

{

memcpy(buf, sbuf, slen);

return (USBD_HID_OUTREPORT_MAX_SZ);

}

}

else if (req == USBD_HID_REQ_EP_INT)

{

USB_ResponseIdle = 1;

}

break;

}

 

break;

 

case HID_REPORT_FEATURE:

break;

}

 

return (0);

}

 

// USB HID override function return 1 if the activity is trivial or response is null

__attribute__((weak))

uint8_t usbd_hid_no_activity(U8 *buf)

{

return 0;

}

 

// USB HID Callback: when data is received from the host

void usbd_hid_set_report(U8 rtype, U8 rid, U8 *buf, int len, U8 req)

{

uint8_t *rbuf;

main_led_state_t led_next_state = MAIN_LED_FLASH;

switch (rtype)

{

case HID_REPORT_OUTPUT:

if (len == 0)

{

break;

}

if (buf[0] == ID_HID_TransferAbort)

{

HID_TransferAbort = 1;

break;

}

 

// execute and store to HID_queue

if (HID_queue_execute_buf(&HID_Cmd_queue, buf, len, &rbuf))

{

if (usbd_hid_no_activity(rbuf) == 1)

{

//revert HID LED to default if the response is null

led_next_state = MAIN_LED_DEF;

}

if (USB_ResponseIdle)

{

hid_send_packet();

USB_ResponseIdle = 0;

}

}

else

{

util_assert(0);

}

 

break;

 

case HID_REPORT_FEATURE:

break;

}

}

 

void HID_queue_init(HID_queue *queue)

{

queue->recv_idx = 0;

queue->send_idx = 0;

queue->free_count = FREE_COUNT_INIT;

queue->send_count = SEND_COUNT_INIT;

}

 

BOOL HID_queue_get_send_buf(HID_queue *queue, uint8_t **buf, int *len)

{

if (queue->send_count)

{

queue->send_count--;

*buf = queue->USB_Request[queue->send_idx];

*len = queue->resp_size[queue->send_idx];

queue->send_idx = (queue->send_idx + 1) % HID_PACKET_COUNT;

queue->free_count++;

return (__TRUE);

}

return (__FALSE);

}

 

BOOL HID_queue_execute_buf(HID_queue *queue, const uint8_t *reqbuf, int len, uint8_t **retbuf)

{

uint32_t rsize;

if (queue->free_count > 0)

{

if (len > HID_PACKET_SIZE)

{

len = HID_PACKET_SIZE;

}

queue->free_count--;

memcpy(queue->USB_Request[queue->recv_idx], reqbuf, len);

rsize = HID_ExecuteCommand(reqbuf, queue->USB_Request[queue->recv_idx]);

queue->resp_size[queue->recv_idx] = rsize & 0xFFFF; //get the response size

*retbuf = queue->USB_Request[queue->recv_idx];

queue->recv_idx = (queue->recv_idx + 1) % HID_PACKET_COUNT;

queue->send_count++;

return (__TRUE);

}

return (__FALSE);

}

如上,我们只需要实现修改如下HID_ExecuteCommand可处理我们收到的收据,并且填入我们发送数据出去队列即可发送出去。

本次我们使用HID工具V1.3.3测试我们的HID功能,打开软件如图2所示:


图2 HID工具连接

点击选择HID设备,选择我们MM32 MCU的HID设备,如图3:


图3 HID工具设备选择

点击连接,发送数据,可以看到图4结果,发送两次共128字节,收到两次数据,共128字节。


图4 HID工具数据收发

以上就是MM32 MCU USB的HID功能,下一节我们继续介绍MM32 MCU USB的WINUSB功能。

来源: 灵动MM32MCU

围观 487

前言

对于 usb (Universal Serial Bus)大家都非常熟悉,通用串行总线,是连接计算机系统与外部设备的一种串口总线标准,也是一种输入输出接口的技术规范,被广泛地应用于个人电脑和移动设备等信息通讯产品,并扩展至摄影器材、数字电视(机顶盒)、游戏机等其它相关领域。

10 年我进入大学的时候,大部分电脑还是标配 usb2.0 的接口,后来才慢慢出了 usb3.0usb3.1 等,现在接口越来越多,包括我知道的早起安卓使用的 micro usb,现在的 type c 接口。而苹果的接口虽然不在 usb 标准里面,但是苹果的设备市场占有率也很大,他的 lighting接口thunderbolt接口 使用率也很高,很多时候这么多的接口类型让人困惑,本文就来讲一讲 usb 标准的版本和接口类型。

串口和并口

不管什么接口,作用都是为了连接外部设备,然后传递数据,而接口发展的目标当然是能够连接更多不同的设备以及获得更高的传输速率。但凡事都要考虑实现的难度和实现的成本,很多时候由于技术或成本的限制我们只能在具体的应用场景采取最合适的方案。串口和并口就是在早起传输速率不是很快的情况下,针对不同的应用场景采取的不同方案。

串口和并口的定义:在一个独立的信道上,每次同时传输1bit为串口,每次同时传输多个bit为并口。从定义上看,并口的传输速率似乎要比串口快,但是为什么在大部分应用场景下并口已经慢慢被淘汰了呢。我们知道就是在我们使用的 usb 以及以前的主办上的并行接口,串行接口内部都是有很多条线路的(比如 usb 或者 lighting接口 上的触电),他们有的用于供电,有的用于接地,有的用于传输信号,还可能有一些其他操作比如控制等。我们想要提高接口的传输速率无非两种方法,一种是提高单根线路的传输速率,另一种是增加线的数量。但是在并行接口的实践中已经发现,多条线路的信号会相互干扰,并且传输距离要有限制,不能太远,比如主板上的并行接口一次传 8bits,如果其中一个信号出错,8 个全部要重发。而串行的结构要简单很多,干扰的问题要小很多,同时成本也更低,我们只要提高单根线路的传输速率就好了,这要比解决干扰的问题成本小很多,而且并口的多条线路之间还要解决数据同步的问题。

简单的说就是串口形容一下就是一条车道,而并口就是有 8 个车道同一时刻能传送8位(一个字节)数据。但是并不是说并口快,由于 8 位通道之间的互相干扰(串扰),传输时速度就受到了限制,传输容易出错。串口没有互相干扰。并口同时发送的数据量大,但要比串口慢。如果并口的干扰问题解决,同时单线速率能够跟串口相同,它的传输速率必然更快,这也是在 21 世纪之前,在单根线路传输速度很慢的情况下,在需要较大传输速度的地方,例如打印机,并口得到广泛使用的原因。但是当前,并口只能在一些需求特殊的场景下发挥作用。

串行接口、并行接口是按照数据传输方式来划分的,串行接口是一大类接口。USBRS232SATAPS/2RS485 等等,这些都属于串行接口;但一般情况下,如果没有特殊说明而只是说“串口”的话,通常特指 RS232 接口。

usb 标准和接口类型

多媒体电脑刚问世时,外接式设备的传输接口各不相同,如打印机只能接 LPT、调制解调器只能接 RS232、鼠标键盘只能接 PS/2 等。繁杂的接口系统,加上必须安装驱动程序并重启才能使用的限制,都会造成用户的困扰。因此,创造出一个统一且支持易插拔的外接式传输接口,便成为无可避免的趋势,USB 应运而生。

USB 最初是由英特尔与微软倡导发起,最大的特点是尽可能得实现热插拔和即插即用。当设备插入时,主机枚举到此设备并加载所需的驱动程序,因此其在使用上远比 PCI 和 ISA 等总线方便。

USB 可以连接的外设有鼠标、键盘、游戏手柄、游戏杆、扫描仪、数字相机、打印机、硬盘和网络等部件。对数字相机这样的多媒体外设 USB 已经是缺省接口;由于大大简化与计算机的连接,USB 也逐步取代并行接口成为打印机的主流连接方式之一。2004 年已经有超过 1亿 台 USB 设备;到 2007 年时,高清晰度数字视频外设是仅有的 USB 未能染指的外设类别,因为他需要更高的传输速率,不过 USB3.1 和 2019 年 USB4 的问世,高清晰度数字视频外设和外接式显卡也能在 USB 播放。

现 USB 标准中,按照速度等级和连接方式分为以下七种版本。注意 USB-IF (USB开发者论坛,USB标准的制定组织)当前正式的主版本号只有 USB 2.0 和 USB 3.2 两个。

USB开发者论坛负责 USB 标准制订,其成员包括:AppleHPNECMicrosoft 和 Intel2001 年底,USB-IF 公布 USB 2.0 规范,与之前的 USB 0.9USB 1.0 和 USB 1.1 一样,该规范完全向下兼容。随后,USB-IF 公布 USB On-The-GoUSB OTG,当前版本:1.0a)作为 USB 2.0 规范的补充标准,使其能够用于在便携设备之间直接交换数据。

USB 的连接器分为 AB 两种,分别用于主机和设备;其各自的小型化的连接器是 Mini-AMini-B 和 Micro-AMicro-B,另外还有 Mini-AB(可同时支持 Mini-A 及 Mini-B)的插口。USB 3.1 版本中引入了支持正反面不区分插入的 C 型。每一种连接器有对应的公口和母口,并且我们用来连接两种不同设备的 USB 线两端会用不同的连接器,这些内容在 USB-IF 都有规定。

紫色的 Type-C 充电速度最高支持 5A 充电、充电功率最高达 100W

具体的版本和对应的接口看下图:

从上面的内容中可以看出,所谓的 2.03.03.13.2 对应的就是 USB-IF 制定的新的 USB 标准的命名,而所谓的 type Ctype A 则是在某个标准实现下具体使用的物理接口(连接器),同一个标准会为不同的设备设计不同的接头。不过几家参与制定标准的大厂都是向着统一接口的目标努力的。

USB Connectors 接头

单独说一下接头,其实真正让使用者搞不清的其实并不是 USB 标准的版本,其实大部分用户也不会去真的把版本区分那么清楚,只要大致知道哪个快哪个慢就行了。真正让大家搞不清的是花样百出的各种接头,Android 上的早起 Micro-B 和现在的 Type-CType-A 里面的 2.03.03.13.2,再加上苹果自己的 lighting 和 thunderbolt,种类繁多,眼花缭乱。

首先我们要知道接头是由 USB-IF 所指定,接头的设计一方面为了支持众多 USB 的基本需求,另一方面也避免以往许多类似串行接头所出现的问题。

  • 接头设计的相当耐用。许多以往使用的接头较脆弱,即使受力不大,有时针脚或零件也会折弯甚至断裂。而 USB 接头的金属导电部分周围有塑料作为保护,而且整个连接部分被金属的保护套围住,因此 USB 接头不论插拔,都不容易受损。由于金属保护套和外围塑料护套的保护,需要较大的力量才能造成 USB 接头明显的损坏。
  • 具有防呆设计,方向相反的插头不可能插到插座里,方向正反很容易感觉出来。所以不可能把 USB 接口插错。
  • 接头能相对便宜地大量生产。
  • 在 USB 网络中,接头被强制使用定向拓扑。USB 不支持环形网络,因此不兼容的 USB 设备之间接口也不兼容。不像其他通讯系统(如 RJ-45 电缆)不能使用转换插头,防止环形 USB 网络产生。
  • 适度的插拔力。USB 电缆和小型 USB 设备能被插口卡住(不需要夹子、螺丝或者其他接口那样的锁扣)。只需要适当力量插拔即可连接周边设备。
  • 由于接头的构造,在将 USB 插头插入 USB 座时,插头外面的金属保护套会先接触到 USB 座内对应的金属部分,之后插头内部的四个触点才会接触到 USB 座。金属保护套会连接到系统的地线,提供路径使静电可以放电,避免因静电通过电子零件而造成损坏。
  • USB 电缆最长允许 5 米,更长的距离需要 HUB

USB 的连接器的插头和插座配对,以及连接不同设备的 USB 线的两端连接器标准都是有规定的,见下两张图。


大部分的连接器都是只能和合身对应的插头插座连接,USB 3.0 的插座大部分都向下兼容。而在 USB 线的部分我们可以看到应用的最广泛的 Type-A 和 Type-C 是适用场景最多的。

这里提一下 USB 4USB 4 于 2019年9月3日 发布。采用 Thunderbolt 3 协议规格,使 Thunderbolt 3设备将能兼容于 USB 4,现有 3.2 及 2.0 也向下兼容。速度方面加倍来到两条通道总共 40Gb/s 的传输速度。

苹果的接口

最后单独说一下苹果的接口,苹果作为一家特立独行,什么东西都自己来的公司,它的接口也都是自己的一套标准。目前在 iphoneipadipod 还有一系列周边设备上使用的都是苹果自己的闪电接口 lighting

闪电是由苹果公司所制作的专属连接器规格,首次出现在 2012 年所发表的 iPhone 5、 iPod Touch 及 iPod nano 等新款手持式消费性电子产品。此连接器针脚为 8 pin,正反面皆可插,尺寸与 Micro USB 相近。闪电取代了使用多年的 30pin 连接器。闪电连接器也是移动市场首个成为主流的正反可插接口,由于插头采用了对称式设计,所以插头的上下两面均分布有相同的针脚。无论用户以何种方向将插头插入接口,其中一组针脚都会同基座中的针脚相连接。当前还有 USB Type-C 也跟着采用这种设计。不同的是,闪电接头的引脚在外面,USB-C 接头的引脚则在里面,且闪电的插座引脚只有一边,USB-C 则两边都有。

相对于移动设备上的 Lighting,在 Mac 上苹果自家的接口就是 Intel 发表的 Thunderbolt 高速串行接口标准,是用来连接电脑和其他设备通用总线。13 年的 Macbook Pro 开始搭载 thunderbolt216 年的 Macbook Pro 开始搭载 Thunderbolt3,而 Thunderbolt3 的 连接器也选择了 Type-C 标准,而最新的 USB 4 标准也采用了 Thunderbolt 3 的协议。

由于支持 Thunderbolt 1, 2 的厂商不多,而且采用 Thunderbolt 的设备大多是高端产品,价格昂贵,加上接口使用的是苹果 Mini Displayport,配件无法用在其他电子设备,普及程度远低于对手 USB。所以 Thunderbolt 3 才与 USB Type-C 的接头兼容,使 Thunderbolt 接口变得更普及。

总结

本文整理了一些关于硬件接口的知识,看完后相信对于各种流行的高速串行接口的标准以及各种连接器的标准都能够有一定的了解。如有错漏,欢迎指正。

参考文章

  1. 并行端口
  2. 为什么串口比并口快? – 又见山人的回答 – 知乎
  3. USB-维基百科
  4. 闪电接头-维基百科
  5. Thunderbolt-维基百科

本博客所有内容采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可

转载文章请注明:USB标准版本和接口类型 - https://www.clloz.com/programming/hardware/2019/11/18/usb-standard-and-connector-type/

围观 312

作者:郭老师

之前由于工作需要,基于 RT-Thread 在 STM32 上实现了 USB 虚拟串口。为了方便大家,我在这里把在正点原子 F429 阿波罗开发板上实现 USB 虚拟串口的详细过程分享给大家,希望可以帮助到更多想要学习 USB 的人。

1、首先,需要更新了一下 RT-Thread 的源代码(因为 RT-Thread 的代码更新很快,短时间内就有可能有很多的代码更新,Github地址:https://github.com/RT-Thread/rt-thread 点star还能领10元柿饼派优惠券)

2、然后进入 rt-thread\bsp\stm32目录下,找到正点原子 F429 阿波罗开发板对应的BSP stm32f429-atk-apollo ,打开此目录。

3、然后查看一下当前 BSP 支持不支持 USB 功能。在当前目录下打开 Env 工具,输入 menuconfig 命令查看,可以看到在硬件配置的片上外设的配置菜单中并没有配置 USB 的选项,看来这个 BSP 还不支持 USB 设备。

4、想到新的 STM32 BSP 所有的 BSP 都是用的同一份驱动,这样就可以根据有没有做好的 USB 驱动来判断有没有 BSP 支持 USB 功能了。打开rt-thread\bsp\stm32\libraries\HAL_Drivers目录。如下所示,可以看到里面果然有 usb 的驱动文件,叫做drv_usbd_fs.c。

5、然后根据同一目录下的 Sconscript 脚本文件,可以查看这个驱动的依赖关系,根据下面的图片可以看出,此驱动文件依赖于 BSP_USING_USBD_FS这个配置项。

6、全局搜索此 stm32 目录下所有的 BSP ,查看哪个 bsp 下有这个配置项。根据这个配置项可以判断出哪个 BSP 支持了 USB 的功能,也可以借此看出依赖关系。搜索发现 F469 的 bsp 有这个配置项,由下图可以看出:打开这个配置的同时,也利用 select 命令打开了 RT_USING_USB_DEVICE 这个配置。

7、修改正点原子 F429 阿波罗 bsp 下 Kconfig 文件,添加这一段配置项。


8、然后,利用 Env 工具根据修改好的配置菜单配置工程。在 目录下输入 menuconfig 配置工程,开启刚刚添加的 usb 驱动的配置项。

9、然后,进入组件配置菜单下设备驱动的配置菜单中的 USB 配置,配置 usb 设备框架的选项。开启虚拟串口。

10、保存并重新生成工程。 发现编译报错。看起来是硬件没有配置。需要打开 stm32CubMX 配置 usb 的硬件引脚。

11、打开stm32f429-atk-apollo\board\CubeMX_Config目录下 stm32CubMX 的工程,配置 usb.


12、开启 usb 功能之后,时钟配置报警告,还需重新配置一下时钟。配置好之后,重新生成代码。

13、由于更新了时钟树,所以还要把stm32f429-atk-apollo\board\CubeMX_Config\Src目录下main.c中的时钟配置函数SystemClock_Config更新到stm32f429-atk-apollo\board目录下的 board.c 文件中。

14、然后重新打开工程,编译,发现还是报错,cannot open source input file "stm32f4xx_hal_exti.h": No such file or directory,注释掉报错的头文件重新编译即可。再次编译,发现没有问题了。


15、下载运行,输入 list_device 命令可以看到注册到系统中的两个 usb 相关的设备。

16、然后在 main函数里添加一段测试代码,编译下载运行。

17、连接开发板上的 USB_SLAVE 接口到电脑上,打开设备管理器,发现多了一个 USB 串行设备,用串口工具打开,就可以接收到从 main 函数里发送过来的消息了。


这样就基于 RT-Thread 在 STM32 上实现 USB 虚拟串口了!

来源: RTThread物联网操作系统

围观 46

页面

订阅 RSS - USB