打印

开源STM32F4xx自定义USB数据传输,支持Windows,Linux,Android,速度高达1MByte/s

[复制链接]
325|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
河童|  楼主 | 2018-7-28 08:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
功能简介:
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 "USBTransmit.h"

#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("设备连接数为:%d
",DevNum);
    //打开设备0
    if(USBOpenDevice(0)){
        printf("打开设备成功!
");
    }else{
        printf("打开设备失败!
");
        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("写数据成功!
");
    }else{
        printf("写数据失败!
");
        getchar();
    }
    printf("正在测试读数据速度,请稍候...
");
    //获取起始时间
#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("读数据失败!
");
        getchar();
    }else{
        printf("读数据成功!
");
    }
    //获取结束时间并打印输出耗时和速度
#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("-----------------------www.embed-net.com-----------------------
");
    printf("读数据字节数: %d MBytes
",(DataNum-DataNumIndex)*PacketSize/(1024*1024));
    printf("读数据消耗时间: %f s
",(EndTime-StartTime)/dfFreq);
    printf("读数据速度: %.3f MByte/s
",(DataNum-DataNumIndex)*PacketSize/((EndTime-StartTime)/dfFreq)/(1024*1024));
    printf("-----------------------www.embed-net.com-----------------------
");
    //释放动态分配的内存空间
    free(pReadDataBuffer);
    //关闭设备0
    ret = USBCloseDevice(0);
    if(ret){
        printf("关闭设备成功!
");
    }else{
        printf("关闭设备失败!
");
    }
    getchar();
    return 0;
}





除去程序运行时间统计代码之后,程序是不是非常简单?

源码下载:http://www.embed-net.com/thread-579-1-1.html

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

452

主题

452

帖子

0

粉丝