OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6928|回复: 7

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

[复制链接]

26

主题

193

帖子

8

精华

金牌会员

Rank: 6Rank: 6

积分
1800
金钱
1800
注册时间
2012-8-23
在线时间
57 小时
发表于 2016-6-7 17:20:40 | 显示全部楼层 |阅读模式
本帖最后由 beyond696 于 2016-6-7 17:23 编辑

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





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

源码下载:http://www.embed-net.com/thread-579-1-1.html
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

115

帖子

0

精华

高级会员

Rank: 4

积分
742
金钱
742
注册时间
2016-1-20
在线时间
189 小时
发表于 2016-10-31 10:32:12 | 显示全部楼层
这是STM32F4xx的单片机源码,我金币也就够买这个,希望楼主不要怪我,我已经为我取得的资料给出了相应的回报

firmware.rar

1.09 MB, 下载次数: 609

回复 支持 1 反对 0

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-6-7 21:50:34 | 显示全部楼层
感谢分享!!!
回复 支持 反对

使用道具 举报

5

主题

277

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1522
金钱
1522
注册时间
2014-5-16
在线时间
217 小时
发表于 2016-6-7 23:48:07 | 显示全部楼层
确实很简单,我做过类似测试,用的两个STM32芯片的全速USB对传数据,最高时貌似超过1.2MB/s
不过除了学习USB协议栈,没什么实用价值
回复 支持 反对

使用道具 举报

17

主题

466

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2161
金钱
2161
注册时间
2013-1-11
在线时间
510 小时
发表于 2016-10-18 22:08:16 | 显示全部楼层
打广告的,你“”开源“”就上传源码啊!
知识是你最好的财富
回复 支持 反对

使用道具 举报

8

主题

163

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5473
金钱
5473
注册时间
2013-3-16
在线时间
644 小时
发表于 2016-10-25 12:06:37 | 显示全部楼层
没钱下载
回复 支持 反对

使用道具 举报

9

主题

209

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1358
金钱
1358
注册时间
2015-12-19
在线时间
108 小时
发表于 2016-11-10 15:10:10 | 显示全部楼层
CCXX 发表于 2016-10-31 10:32
这是STM32F4xx的单片机源码,我金币也就够买这个,希望楼主不要怪我,我已经为我取得的资料给出了相应的回报

感谢你的无私奉献  来生做我衣食父母
求指导!!!兄弟
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2020-11-3
在线时间
1 小时
发表于 2020-11-3 14:49:21 | 显示全部楼层
打不开
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-29 23:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表