csr usb spi怎么用_如何借助Windows库直接访问USB端口,零基从入门(1)

在《C#程序与单片机通信时,如何自动初始化串口(1)?》文章里,介绍了如何通过SerialPort控件,实现对虚拟串口的读写,那种方法比较简单。随后的几篇文章,我介绍一种直接通过Windows库函数,实现对USB端口的访问,这是一种更底层的操作,当然用起来也就更加灵活,上周刚刚测试成功,也让我对USB有了更深刻的理解。

71a60f4926c9faa2526081955cf9cdd6.png

USB驱动

在嵌入式系统里,USB相对于其它如串口,SPI等外设,要复杂的多,不过随着USB的应用越来越广,学会使用USB是非常重要的。现在USB设备都是即插即用的(Plug and Play, PnP)设备。那么PC机是怎么知道插入的设备是什么,又如何实现与USB设备的读写的呢?

为了保证内容的连惯性。先简单介绍一下USB描述符。简单的说,描述符就是一些连接存储的数据结构,通过第一个结构,可以解析出第二个结构的信息,通过第二个结构,可以解析出第三个结构的信息,如此下去。由此可见,USB描述符是逐个解析的过程。每个描述符的第一个字节是说明了本结构的字节数,第二个字节说明了本结构的类型,从第三字节开始是具体数据。这些描述符定义了USB的所有信息,包含厂家及主机如何与之通信。常用的几种描述符如下:

ab099b126ca38cad733cde280e120a62.png

描述符

1.USB设备描述符

每个USB设备都定义了一个自己的设备描述符,它是第一个描述符。我们在电脑设备管理器里看到的信息,都在这个结构里定义。下面是一个PIC单片机的设备描述符结构。

typedef struct _USB_DEVICE_DESCRIPTOR {

UCHAR bLength;//本结构字节数

UCHAR bDescriptorType;//本结构类型

USHORT bcdUSB;//版本2.0,3.0?

UCHAR bDeviceClass;//设备类型

UCHAR bDeviceSubClass;//子类型

UCHAR bDeviceProtocol;//通信协议

UCHAR bMaxPacketSize0;

USHORT idVendor;//厂家代码

USHORT idProduct;//产品代码

USHORT bcdDevice;//版本

UCHAR iManufacturer;

UCHAR iProduct;

UCHAR iSerialNumber;

UCHAR bNumConfigurations;//配置描述符数量

} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;

设备插入时,PC机会自动读取这个结构值,通过解析这个结构,PC会知道设备的类型(块设备、通信设备等)、VID(厂家代码)、PID(产品代码)及配置描述符的数量。

146fe4df7749623146dff68590094a01.png

设备描述符

2.配置描述符

每个设备都至少有一个配置描述符。主要功有二个,一是指明本配置有几个接口(即虚拟设备数量,如一个USB可以多个串口,但是同一时候只能打开其中一个),很多时候只有一个接口。二是说明本设备在些配置下的功耗。

typedef struct _USB_CONFIGURATION_DESCRIPTOR {

UCHAR bLength;

UCHAR bDescriptorType;//类型

UORT wTotalLength;//配置总字节数

UCHAR bNumInterfaces;//接口数量

UCHAR bConfigurationValue;//本配置索引

UCHAR iConfiguration;//字索引数量

UCHAR bmAttributes;//位信息

UCHAR MaxPower;//功耗

} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;

当有多个配置时,主机通过bConfigurationValue可以选择启用哪一个配置,进一步可以选哪一个接口。至少有一个接口。

3.接口描述符

紧随上面的结构,是接口描述符。

typedef struct _USB_INTERFACE_DESCRIPTOR {

UCHAR bLength;

UCHAR bDescriptorType;

//本接口的索引

UCHAR bInterfaceNumber;

//本接口设置索引

UCHAR bAlternateSetting;

//端点数量

UCHAR bNumEndpoints;

//类型

UCHAR bInterfaceClass;

//子类型

UCHAR bInterfaceSubClass;

//通信协议

UCHAR bInterfaceProtocol量

UCHAR iInterface;

} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;这个

这个结构指明具体功能。包括端点的数量 ,功能类型(有些在设备描述符中定义,但是这里的信息更加具体)。

4.端点描述符

每个端点都有一个这个结构。指明端点的地址(即端点号),缓冲区大小,传输方式。

typedef struct _USB_ENDPOINT_DESCRIPTOR {

UCHAR bLength;

UCHAR bDescriptorType;

UCHAR bEndpointAddress;

UCHAR bmAttributes;

//缓冲大小

USHORT wMaxPacketSize;

//主机查询间隔

UCHAR bInterval;

} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;

注意,USB传输是主从模式,都是由主机发起的。传输方向也是相对主机而言的。这些描述符是层次递进的关系。上一层结构除了说明自身的信息外,还指明了下一个结构是什么。

本文是为C#调用Window库函数作一个技术准备,因为后面的函数里要用到这些概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值