STM32 USB 上位机程序实现

发布者:码字先生最新更新时间:2018-09-17 来源: eefocus关键字:STM32  USB  上位机程序 手机看文章 扫描二维码
随时随地手机看文章

libusb 介绍


libusb是开源的C库,使用该库是的用户可以在应用程序中直接访问 USB 设备,无需为 USB 设备编写内核驱动。libusb支持多个平台 (linux, window, ios),所以可以很方便地将应用程序移植到其他平台。


linux libusb 安装


从网上下载libusb的源码,下载地址:http://www.libusb.org/, 下载后编译安装。


# tar jxvf libusb-1.0.20.tar.bz2


# cd libusb-1.0.20

# ./configure

# make

# sudo make install


ubuntu下可以通过以下命令快速安装。


sudo apt-get isntall libusb*


安装后,libusb的头文件被安装在/usr/local/include/libusb-1.0 ,链接库被安装在/usr/loacal/lib目录下。


usb bulk 传输例程


这个例程演示如何使用 libusb 库,编写 USB bulk xfer 上位机demo,可以正常接收和发送数据。注意,修改程序中的 VID 和 PID 的值和你 device 板子上所定义的一致,传输数据块的大小不要超过 device 定义的最大传输长度。



#include

#include

#include

#include


#include "libusb.h"


#define VID 0x8888

#define PID 0x0088


#define edp2in 0x82

#define edp2out 0x02


int main(void)

{

    libusb_device **devs, *dev;

    int ret, i;

    ssize_t cnt;

    usb_pro_t usb_pro;

    struct libusb_device_handle *handle = NULL;

    libusb_context *ctx = NULL;


    ret = libusb_init(&ctx);

    if (ret < 0)

        return -1;


    libusb_set_debug(ctx, 3);


    cnt = libusb_get_device_list(NULL, &devs);

    if (cnt < 0) {

        printf("no usb dev on bus\r\n");

        return  -1;

    }


    i = 0;

    while((dev = devs[i++]) != NULL) {


        ret = libusb_get_device_descriptor(dev,&desc);

        if (ret < 0) {

            printf("failed to get device descriptor");

            goto error;

        }


        if ((desc.idVendor == VID) && (desc.idProduct == PID)) {

            printf("bLength: 0x%04x\r\n", desc.bLength);

            printf("bDescriptorType: 0x%04x\r\n", desc.bDescriptorType);

            printf("bcdUSB: 0x%04x\r\n", desc.bcdUSB);

            printf("bDeviceClass: 0x%04x\r\n", desc.bDeviceClass);

            printf("bDeviceSubClass: 0x%04x\r\n", desc.bDeviceSubClass);

            printf("bDeviceProtocol: 0x%04x\r\n", desc.bDeviceProtocol);

            printf("bMaxPacketSize0: 0x%04x\r\n", desc.bMaxPacketSize0);

            printf("vendor id: 0x%04x\r\n", desc.idVendor);

            printf("product id: 0x%04x\r\n", desc.idProduct);

            printf("bcdDevice: 0x%04x\r\n", desc.bcdDevice);

            printf("iManufacturer: 0x%04x\r\n", desc.iManufacturer);

            printf("iProduct: 0x%04x\r\n", desc.iProduct);

            printf("iSerialNumber: 0x%04x\r\n", desc.iSerialNumber);

            printf("bNumConfigurations: 0x%04x\r\n", desc.bNumConfigurations);


        }


    }


    handle = libusb_open_device_with_vid_pid(ctx, VID, PID);


    if (handle == NULL) {

        printf("cant't open device\r\n");

        goto error;

    } else {

        printf("open device\r\n");

    }


    libusb_free_device_list(devs, 1);


    if (libusb_kernel_driver_active(handle, 0) ==1) {

        printf("kernel driver active, detach it \r\n");


        if (libusb_detach_kernel_driver(handle, 0) == 0) {

            printf("detached kernel driver\r\n");

        }

        else {

            goto error;

        }

    }


    ret = libusb_claim_interface(handle, 0);

    if (ret < 0) {

        printf("can't claim interface\r\n");

        goto error;

    } else {

        printf("claimed interface\r\n");

    }


    char data[64];

    int actual_len = 0;

    int didi = 1000;

    for (int i = 0; i< 1000; i++) {

        memset(data, 0, sizeof(data));

        /*  receive data from device  */

        /*

        ret = libusb_bulk_transfer(handle, edp2in, data, 64, &actual_len, 0);


        if (actual_len = 0) {

            printf("received nothing\r\n");

        } else {

            printf("bulk transfer: %s\r\n", data);

        }


        usleep(200000);

        */


        char *str = "am host";


        sprintf(data, "am host %d\r\n", i);


        ret = libusb_bulk_transfer(handle, edp2out, data, strlen(data), &actual_len, 0);


        if (actual_len != 0) {

            printf("send data: %s\r\n", data);

        }


        usleep(200000); 

    }


    libusb_close(handle);


error:


    printf("free device list\r\n");

    libusb_free_device_list(devs, 1);


    libusb_exit(NULL);


    return 0;

}


编译


编译代码可以使用 makefile 文件,也可以是使用命令行命令编译,这里给出两种编译方法。


makefile


CC = gcc


# your libusb library path, be careful your path.

LDIR = /usr/loacal/lib


# link flag

LFLAG = -lusb-1.0


# libusb hearder file path

INCLUDES = /usr/local/include/libusb-1.0


CFLAGS = -I$(INCLUDES) -std=c99


src = $(wildcard *.c)


obj = $(patsubst %.c, %.o, $(src))


.PHONY: all clean


all: main


main: $(obj)

    $(CC)   $(obj) -o main -L$(LDIR) $(LFLAG)


%.o:%.c

    $(CC) $(CFLAGS) -c $< -o $@


clean:

    @-rm -f main $(obj)


命令行编译 

命令中-I/usr/local/include/libusb-1.0 告诉编译器 libusb 的头文件所在的路径。-L/usr/local/lib/ 告诉链接器所要链接的库文件路径。-lusb-1.0 告诉编译器需要链接 libusb-1.0.so这个库。

 gcc -I/usr/local/include/libusb-1.0 -std=c99 main.c -o main -L/usr/local/lib/ -lusb-1.0


运行


编译后会在当前目录下生成一个名叫“main“的可执行文件,运行这个文件。如果打开USB设备时出错提示permission error,那么使用


# sudo ./main


运行后,HOST每隔200ms 向 device 发送一个数据包。


源码下载


我的源码已上传到http://download.csdn.net/detail/chengwenyang/9479835 ,包含STM32F4Discovery板子的 usb bulk 传输的工程文件和 使用 libusb 编写的上位机程序。


关键字:STM32  USB  上位机程序 引用地址:STM32 USB 上位机程序实现

上一篇:STM32F4中USB与PC双向通信
下一篇:使用stm32F10XX芯片开发的USB HID 双向通信

推荐阅读最新更新时间:2024-03-16 16:14

关于STM32的计数和延时
读者*丽杰*问: 问个问题,我想要获得比较准确的延时时间,用stm32哪个时钟,通过什么方法让他准确? 我的回答: 通过STM32的任意一个TIM定时器都可以达到比较精确的延时时间。 Ⅰ 关于STM32的计数和延时 在STM32中,具有计数(或计时)功能的模块基本都能实现延时功能。如:系统滴答SysTick、定时器TIM、实时时钟RTC、看门狗WDG。 精确延时一般使用定时器TIM即可实现。当然,是否精确,取决于你的主频(也就是晶振)是否准确,如果主频精确,那么实现的延时也一定精确。 一般来说,常温下实现us微秒级的延时,误差还是挺小的(应该说挺精确)。拿F407,主频168M来说,可以实现几十ns纳秒
[单片机]
关于<font color='red'>STM32</font>的计数和延时
linux上搭建stm32开发环境 vscode+gcc+stm32cubeMX 和 vscode+platformIO
一、软件清单: VSCode:应用商店安装 或 sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make sudo apt-get update sudo apt-get install ubuntu-make sudo umake web visual-studio-code arm-none-eabi-gcc: sudo apt-get install gcc-arm-none-eabi sudo apt-get install gdb-arm-none-eabi del /del 或 手动下载安装:https://launchpad.net/gcc-arm-embedd
[单片机]
linux上搭建<font color='red'>stm32</font>开发环境 vscode+gcc+stm32cubeMX 和 vscode+platformIO
基于USB的数据采集系统的设计与研究
  1引 言   数据采集作为获取信息的手段,越来越多的应用在各种工业系统中。目前数据采集系统多以PCI,ISA或。   EPP/ECP等完成数据的传输,这些方式开发调试比较困难,安装不便,通用性和可移植性差;而且PC上的插槽数量、地址、中断资源的有限导致这些方式的可扩展性差[1]。目前广泛应用的USB总线接口具有安装方便、高带宽、易于扩展等优点,USB 2.O的传输速率可达到480 Mb/s,已逐渐成为现代数据传输的发展趋势之一[2]。   2 EZ-USB FX2以及CY7C68013的特点   本文选择C2ypress公司LISB接口芯片CY7C268013(56一pin),该芯片属于EZ-IJSB FX2系列。
[嵌入式]
STM32中的独立看门狗IWDG
一. 简述STM32中的看门狗系统 STM32F10xxx内置两个看门狗,一个是IWDG(独立看门狗),一个是WWDG(窗口看门狗),两个看 门狗设备(可用来检测和解决由软件错误引起的故障。 当计数器达到给定的超时值时,IWDG会产生系统复位。而WWDG会触发中断。这篇文章主要讲解一下IWDG。 二. 关于 独立看门狗IWDG 1. 独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。 2. IWDG主要性能 自由运行的递减计数器 时钟由独立的RC振荡器提供(可在
[单片机]
[HAL库]STM32之DMA方式串口发送
目的:使用cube软件实现DMA方式的数据发送和接收 1.在cube Pinout中打开USART1,方式为异步通讯(Asynchronous); 2.在cube Configuration中打开USART1 Configuration,添加DMA通道(接收改为循环方式)以及打开usart的全局中断,在NVIC中调整优先级 3.生成代码,在keil中进行以下修改: 1)在main文件中建立发送缓存区和接收缓存区(两个定常数组) 使用HAL_UART_Receive_DMA(&huart1,aRxBuffer,sizeof(aRxBuffer)) 进行DMA的接收(等待接收) 使用HAL_UART_Transmi
[单片机]
USB-IF电池充电规格与测试
隶属USB-IF下的Battery Charging 工作小组(主要参加者多为手机相关厂商,如Nokia, Qualcomm, Motorola, 中国大陆TMC等),历经多年的讨论,即将推出最新版(V1.1)的「电池充电规格」,此规格主要在制定透过USB接口充电的装置与提供透过USB接口充电的设备(如系统、充电座)间的规范,特别是把USB标准的供电量从500mA提升到1.5A的最大可能,企图统一目前混乱的局面(各国都有自己订定的规格),也避免用户因为透过USB接口充电而遭遇问题。 此外该电池充电规格还允许PC和集线器提供更高等级的电流,因而能够缩短所连接便携式设备(Portable Device)的充电时间。就如同USB-IF总
[嵌入式]
意法半导体与 Sierra Wireless合作,简化物联网连接方案部署
整合STM32 MCU的低功耗、高性能和安全性与Sierra Wireless 的弹性的全球蜂窝物联网接入和边缘设备上云方案,简化物联网设备部署 中国,2021 年11月11日-- 服务多重电子应用领域的全球半导体领导者意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)和全球领先的物联网服务提供商Sierra Wireless宣布了一项合作协议,让STM32微控制器(MCU)开发社区能够利用Sierra Wireless灵活的蜂窝物联网接入和边缘设备云连接解决方案。 该协议可帮助解决方案开发者应对创建和部署物联网解决方案涉及的各种挑战,包括设备研发、蜂窝网络接入和与云服务连接等
[物联网]
意法半导体与 Sierra Wireless合作,简化物联网连接方案部署
基于EZ-USB 2100系列单片机的PCB探测系统开发
1 引言 在进行PCB反设计时,需要首先对电路板进行探测,得出所有元器件管脚之间的连接关系;接着再利用相应的软件对探测结果进行分析处理,最终还原出PCB的原理图。假设电路板上有 次。由于大规模PCB上器件管脚众多,因此完全依靠手工探测不仅效率低下,而且极易出错。为了提高PCB探测的效率和准确性,本文提出了一种基于EZ-USB 2100系列单片机的PCB探测系统的设计与实现方案。该系统有 个探测头,分别连接到电路板的 个器件管脚上。在单片机的控制下,系统自动的探测这个管脚间的连接关系;然后,系统依据探测选择算法,选取下一组 个管脚进行探测,依此循环,直到所有的 个器件管脚均探测完毕。采用EZ-USB 2100系列单片机进行开发,不
[单片机]
基于EZ-<font color='red'>USB</font> 2100系列单片机的PCB探测系统开发
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved