功能简介:
1,自定义USB协议实现数据传输,采用Bulk传输模式,两个Bulk端点,一个输入,一个输出;
2,PC端驱动支持Windows,Linux,Mac,Android,树莓派,除了安卓之外,其他的代码为同一套代码,只需要在不同的系统下重新编译即可;
3,非常简单的USB接口,只需要更换PID和VID即可使用在自己的系统中,PC和单片机端单次收发数据最大可达64KByte;
4,安卓端支持USB设备插拔检测,插入设备之后自动弹出授权对话框授权,拔出设备之后可以通过回调函数方式通知上层应用;
5,所有源码全部开放,毫无保留,程序逻辑清晰,注释清楚详细;
部分系统实测图:
代码构成简介:
为方便移植管理,USB底层数据传输封装成了一个名为USBTransmit的库,当然这个库也会提供全部源码,上层应用基于这个库实现USB设备的管理和数据收发即可;
USBTransmit库接口定义如下:
#ifndef __USBTRANSMIT_H__
#define __USBTRANSMIT_H__
// Device endpoint(s)
#define EP0 0x00
#define EP1_IN 0x81 //wMaxPacketSize: 64 Bulk
#define EP1_OUT 0x01 //wMaxPacketSize: 64 Bulk
int USBScanDevice(int usb_pid,int usb_vid);
bool USBOpenDevice(int DevIndex);
bool USBCloseDevice(int DevIndex);
bool USBCheckDevice(int DevIndex);
bool USBBulkWriteData(int DevIndex,int pipenum,char *sendbuffer,int len,int waittime);
int USBBulkReadData(int DevIndex,int pipenum,char *readbuffer,int len,int waittime);
bool USBIntWriteData(int DevIndex,int pipenum,char *sendbuffer,int len,int waittime);
int USBIntReadData(int DevIndex,int pipenum,char *readbuffer,int len,int waittime);
bool USBCtrlData(int DevIndex,int requesttype,int request,int value, int index, char *bytes, int size,int waittime);
#endif
设备扫描打开关闭使用USBScanDevice,USBOpenDevice,USBCloseDevice函数,数据传输使用USBBulkWriteData,USBBulkReadData函数,是不是非常简单!
下面这个是C/C++版本的上层代码:
// USBTransmitTest.cpp : Defines the entry point for the console application.
//
#ifdef OS_UNIX
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#else
#include <Windows.h>
#endif
#include <stdio.h>
#include <memory.h>
#include &quot;USBTransmit.h&quot;
#define USB_VID 0x0483
#define USB_PID 0x5710
int main(int argc, char* argv[])
{
int DevNum;
//单位为包
int DataNum = 500;
//每次传输的数据字节数,该参数必须和单片机中的参数完全匹配,该参数不能大于或等于64K
int PacketSize = 32*1024;
int DataNumIndex = DataNum;
int ret;
char *pReadDataBuffer = (char *)malloc(PacketSize);
char WriteDataBuffer[8];
//扫描设备连接数,需要初始化
DevNum = USBScanDevice(USB_PID,USB_VID);
printf(&quot;设备连接数为:%d
&quot;,DevNum);
//打开设备0
if(USBOpenDevice(0)){
printf(&quot;打开设备成功!
&quot;);
}else{
printf(&quot;打开设备失败!
&quot;);
getchar();
return 0;
}
DataNumIndex = DataNum;
//告诉设备即将要读取的数据包数
WriteDataBuffer[0] = DataNum>>24;
WriteDataBuffer[1] = DataNum>>16;
WriteDataBuffer[2] = DataNum>>8;
WriteDataBuffer[3] = DataNum>>0;
//高速设备每包数据的长度
WriteDataBuffer[4] = PacketSize>>24;
WriteDataBuffer[5] = PacketSize>>16;
WriteDataBuffer[6] = PacketSize>>8;
WriteDataBuffer[7] = PacketSize>>0;
ret = USBBulkWriteData(0,EP1_OUT,WriteDataBuffer,8,100);
if(ret){
printf(&quot;写数据成功!
&quot;);
}else{
printf(&quot;写数据失败!
&quot;);
getchar();
}
printf(&quot;正在测试读数据速度,请稍候...
&quot;);
//获取起始时间
#ifdef OS_UNIX
struct timeval StartTime_t,EndTime_t;
long long StartTime,EndTime;
double dfFreq = CLOCKS_PER_SEC;
gettimeofday(&StartTime_t,NULL);//开始计时
#else
LARGE_INTEGER litmp;
LONGLONG StartTime,EndTime;
double dfFreq;
QueryPerformanceFrequency(&litmp);//取得高精度运行计数器的频率f,单位是每秒多少次(n/s),
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
StartTime = litmp.QuadPart; //开始计时
#endif
//循环读取数据
do{
ret = USBBulkReadData(0,EP1_IN,pReadDataBuffer,PacketSize,100);
if(ret != PacketSize){
break;
}else{
DataNumIndex--;
}
}while(DataNumIndex > 0);
if(DataNumIndex > 0){
printf(&quot;读数据失败!
&quot;);
getchar();
}else{
printf(&quot;读数据成功!
&quot;);
}
//获取结束时间并打印输出耗时和速度
#ifdef OS_UNIX
gettimeofday(&EndTime_t,NULL); //终止计时
StartTime = StartTime_t.tv_sec*1000000+StartTime_t.tv_usec;
EndTime = EndTime_t.tv_sec*1000000+EndTime_t.tv_usec;
#else
QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
EndTime = litmp.QuadPart; //终止计时
#endif
//打印输出读数据速度
printf(&quot;-----------------------www.embed-net.com-----------------------
&quot;);
printf(&quot;读数据字节数: %d MBytes
&quot;,(DataNum-DataNumIndex)*PacketSize/(1024*1024));
printf(&quot;读数据消耗时间: %f s
&quot;,(EndTime-StartTime)/dfFreq);
printf(&quot;读数据速度: %.3f MByte/s
&quot;,(DataNum-DataNumIndex)*PacketSize/((EndTime-StartTime)/dfFreq)/(1024*1024));
printf(&quot;-----------------------www.embed-net.com-----------------------
&quot;);
//释放动态分配的内存空间
free(pReadDataBuffer);
//关闭设备0
ret = USBCloseDevice(0);
if(ret){
printf(&quot;关闭设备成功!
&quot;);
}else{
printf(&quot;关闭设备失败!
&quot;);
}
getchar();
return 0;
}
除去程序运行时间统计代码之后,程序是不是非常简单?
源码下载:http://www.embed-net.com/thread-579-1-1.html |
|