C++ USBXPRESS程序开发

一、前言

C++的开发过程中,有时候是需要通过USB接口进行数据传输和解析操作的,对于这种情况,需要通过动态库来进行辅助链接,USBXPRESS就是一种用于调用USB接口的专用库。
他为一个简单的,高层次的应用程序接口(API)为主机软件和设备固件连接提供了完整的USB接口。
适用的设备:C8051F32x, C8051F34x, C8051F38x, C8051T32x, C8051T62x, CP2101, CP2102, CP2103, CP2104, CP2105


二、接口简介

USBXPRESS提供了丰富的接口,可以实现各种基本的USB设备的查找,链接,写入,读取等操作,本文只涉及以下操作,更多的操作基本参考下面接口的使用方式。
打开一个设备并向设备区读取数据是必须要实现以下几个接口的:
SI_GetNumDevices() - 返回链接设备的数量
SI_Open() - 打开设备并返回设备句柄
SI_Close() -取消挂起的IO和关闭设备
SI_Read() - 重设备中读取一个数据块
SI_Write() - 往设备里写一个数据块

在使用之前,首先做好相关的动态库的导入和链接工作,然后把需要使用USBXPRESS的类中引入头文件。

#include "./Include/SiUSBXp.h"

进一步,打开引入的SiUSBXp.h
包含下面的头文件:

#include <Windows.h>

这样再编译就不会提示找不到方法等错误了。

1、SI_GetNumDevices()介绍和实现

原型:SI_STATUS SI_GetNumDevices(LPDWORD NumDevices)
参数:1。NumDevices:一个DWORD类型的变量,返回的是存放设备数变量的地址
返回值: SI_STATUS=SI_SUCCESS or SI_DEVICE_NOT_FOUND or SI_INVALID_PARAMETER

输入的是一个DWORD类型的引用,结束后将会得到一个设备数量的地址。
DWORD是无符号的,相当于unsigned long ,它是MFC的数据类型。
代码实现如下:

DWORD dwNumDevices=0;//连接usb个数

SI_STATUS status_haveDev = SI_GetNumDevices(&dwNumDevices);
SI_STATUS status_haveDev;
if(status_haveDev==SI_DEVICE_NOT_FOUND)
{
    return;
}

2、SI_Open() 介绍和实现

原型:SI_STATUS SI_Open (DWORD DeviceNum, HANDLE *Handle)
参数:
1 DeviceNum:设备的索引,从0开始
2 Handle:一个存放设备句柄的指针变量,为后来的访问提供的句柄
返回值:SI_STATUS = SI_SUCCESS or
SI_DEVICE_NOT_FOUND or
SI_INVALID_PARAMETER or
SI_GLOBAL_DATA_ERROR

HANDLE handle; //标识符,关键性句柄,可以用来后续的变量查找
SI_STATUS status_open;
status_open = SI_Open(dwNumDevices-1,&handle);

一般情况下,需要把handle的值进行保存,后续的读取和写入都需要用到这个句柄。


3、SI_Write()介绍和实现

原型:SI_STATUS SI_Write (HANDLE Handle, LPVOID Buffer, DWORD NumBytesToWrite,DWORD NumBytesWritten, OVERLAPPED o = NULL)
参数:
1 Handle:SI_Open函数返回的句柄。
2 Buffer:要发送到设备的字节数组的地址。
3 NumBytesToWrite:写到设备中的字节数(0-4096 bytes)
4 NumBytesWritten:实际写入到设备中的字节数组的地址(DWORD类型)
5 (Optional):异步写的OVERLAPPED对象的地址。
返回值:SI_STATUS = SI_SUCCESS or
SI_WRITE_ERROR or
SI_INVALID_REQUEST_LENGTH or
SI_INVALID_PARAMETER or
SI_INVALID_HANDLE or
SI_WRITE_TIMED_OUT or
SI_IO_PENDING or
SI_SYSTEM_ERROR_CODE or
SI_DEVICE_IO_FAILED

Buffer:参数Buffer就是要写入的命令,写入的命令应该是unsigned char ch[x]的一个byte的数组,具体的命令格式就根据自己的外设协议决定。
NumBytesToWrite:这个是写入命令的长度,也就是Buffer的长度,类型是DWORD。

代码如下

unsigned char ch[2];

//这个数组内容自定
ch[0] = 0x68;
ch[1] = 0x12;

DWORD dwBytesToRead=2;
DWORD dwBytesReturned ;

SI_STATUS state_wirte;
//数据写入
state_wirte = SI_Write(handle, ch, dwBytesToRead, &dwBytesReturned);

4、SI_Read() 介绍和实现

原型:SI_STATUS SI_Read (HANDLE Handle, LPVOID Buffer, DWORD NumBytesToRead,DWORD NumBytesReturned, OVERLAPPED o = NULL)
参数:
1 Handle:SI_Open函数返回的设备句柄。
2 Buffer:存放读取数据的字符字节数组的地址。
3 NumBytesToRead:读取设备的数据缓冲区字节数(0-64KB)
4 NumBytesReturned:DWORD类型的变量地址,存放的是读入缓冲区的字节数
5 (Optional):可用于异步读取的OVERLAPPED对象的地址
返回值:SI_STATUS = SI_SUCCESS or
SI_READ_ERROR or
SI_INVALID_PARAMETER or
SI_INVALID_HANDLE or
SI_SI_READ_TIMED_OUT or
SI_IO_PENDING or
SI_SYSTEM_ERROR_CODE or
SI_INVALID_REQUEST_LENGTH or
SI_DEVICE_IO_FAILED

这部分和写入是非常像的,代码如下:

//设置一个足够长的数组来接受读取的数据,一般情况下长度和协议有关,看协议返回多少字节的数据
unsigned char ch2[2048];

DWORD dwBytesToRead2=2048;
DWORD dwBytesReturned2=0 ;

//读取内容
SI_STATUS status_read = SI_Read(handle, ch2, dwBytesToRead2, &dwBytesReturned2);

读取成功后,数据便存放在ch2中,后续操作就是对ch2中的数据进行操作了


5、SI_Close()介绍和实现

原型:SI_STATUS SI_Close (HANDLE Handle)
参数:1 Handle:SI_Open函数返回的句柄
返回值:SI_STATUS = SI_SUCCESS or
SI_INVALID_HANDLE or
SI_SYSTEM_ERROR_CODE or
SI_GLOBAL_DATA_ERROR

如果使用完成后记得调用close方法,传入句柄保证设备关闭,不然会影响下一次的调用


三、总结

使用USBXPRESS程序进行USB数据通信的主要接口就是上面的接口,实现了这些接口基本功能就可以实现查找、打开、写入、读取数据了。
基本上调用的顺序也是这样的一个顺序步骤:
1、SI_GetNumDevices()—>SI_Read() //完成后等待写入读取数据
2、SI_Write()—>SI_Read()//完成后进行后续的其他写入读取操作
3、SI_Close()

如果需要获取链接的设备的信息,那么可以采用下面的方法:

SI_GetProductString()

原型:SI_STATUS SI_GetProductString(DWORD DeviceNum,LPVOID DeviceString,DWORD Option)
参数:
1 DeviceNum:设备唯一序列号或描述字符串
2 DeviceString:SI_DEVICE_STRING类型,返回一个设备描述符或字符串或一个代表终止的NULL。
3 Options:DWORD类型的标志,以确定是否在DeviceString中包含一个序列号。产品说明,供应商ID,产品ID字符串。
返回值:SI_STATUS = SI_SUCCESS or
SI_DEVICE_NOT_FOUND or
SI_INVALID_PARAMETER
代码如下:

SI_DEVICE_STRING  DeviceString;
DWORD Option=0;

SI_STATUS status_haveProStr =SI_GetProductString(dwNumDevices-1,DeviceString,Option);

这里有个小坑,开发的文档将DeviceString定义为LPVOID ,单纯看接口的时候,SI_GetProductString的定义如下:

SI_USB_XP_API
SI_STATUS WINAPI SI_GetProductString(
    DWORD dwDeviceNum,
    LPVOID lpvDeviceString,
    DWORD dwFlags
    );

没毛病,对于DeviceString是确实是LPVOID类型
然而如果你要真的这么做,程序运行会有时候崩溃。
仔细查看文档,有这么一句话:

DeviceString:SI_DEVICE_STRING类型,返回一个设备描述符或字符串或一个代表终止的NULL。

所以,传入的DeviceString必须是SI_DEVICE_STRING类型的才可以。

基本上内容就这么多,其他的接口也是如此。
对于参数的类型上,还是要严格参考文档执行,这才不会出错。

附上开发文档的链接:
https://wenku.baidu.com/view/c8f8a5aed1f34693daef3e1f.html?from=search
ps:百度真是个好东西23333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值