1. 程式人生 > >STM32 USB 上位機程式實現

STM32 USB 上位機程式實現

libusb 介紹

libusb是開源的C庫,使用該庫是的使用者可以在應用程式中直接訪問 USB 裝置,無需為 USB 裝置編寫核心驅動。libusb支援多個平臺 (Linux, window, iOS),所以可以很方便地將應用程式移植到其他平臺。

linux libusb 安裝

# tar jxvf libusb-1.0.20.tar.bz2

# cd libusb-1.0.20
# ./configure
# make
# sudo make install
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

ubuntu下可以通過以下命令快速安裝。

sudo apt-get isntall libusb*
  • 1
  • 1

安裝後,

libusb的標頭檔案被安裝在/usr/local/include/libusb-1.0 ,連結庫被安裝在/usr/loacal/lib目錄下。

usb bulk 傳輸例程

這個例程演示如何使用 libusb 庫,編寫 USB bulk xfer 上位機demo,可以正常接收和傳送資料。注意,修改程式中的 VID 和 PID 的值和你 device 板子上所定義的一致,傳輸資料塊的大小不要超過 device 定義的最大傳輸長度。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#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; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137

編譯

編譯程式碼可以使用 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 [email protected]

clean:
    @-rm -f main $(obj)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 命令列編譯 
    命令中-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
  • 1
  • 2
  • 1
  • 2

執行

編譯後會在當前目錄下生成一個名叫“main“的可執行檔案,執行這個檔案。如果開啟USB裝置時出錯提示permission error,那麼使用

# sudo ./main
  • 1
  • 1

執行後,HOST每隔200ms 向 device 傳送一個數據包。

原始碼下載

相關推薦

STM32 USB 上位程式實現

libusb 介紹 libusb是開源的C庫,使用該庫是的使用者可以在應用程式中直接訪問 USB 裝置,無需為 USB 裝置編寫核心驅動。libusb支援多個平臺 (Linux, window, iOS),所以可以很方便地將應用程式移植到其他平臺。 linux li

基於stm32的自定義HID裝置開發與上位通訊實現(附原始碼)

現在主流的安卓手機資料連線線,Mini-usb、Micro-usb,Type-c,產品追隨主流,非聯網裝置,摒棄ST-LINK、JLINK,直接用usb資料傳輸升級。主要實現與HID裝置的通訊即人機互動。本文主要介紹了HID裝置的下位機通訊連線與上位機裝置識別。 下位機:

基於MFC的USB上位開發(5)下環路模組

延伸閱讀: 基於MFC的USB上位機開發(1)概述 基於MFC的USB上位機開發(2)速度測試模組 基於MFC的USB上位機開發(3)資料傳輸模組 基於MFC的USB上位機開發(4)環路模組 基於MFC的USB上位機開發(5)下環路模組 目錄 1. 設計思路

基於MFC的USB上位開發(4)環路模組

延伸閱讀: 基於MFC的USB上位機開發(1)概述 基於MFC的USB上位機開發(2)速度測試模組 基於MFC的USB上位機開發(3)資料傳輸模組 基於MFC的USB上位機開發(4)環路模組 基於MFC的USB上位機開發(5)下環路模組 目錄 1. 設計思路

基於MFC的USB上位開發(3)資料傳輸模組

延伸閱讀: 基於MFC的USB上位機開發(1)概述 基於MFC的USB上位機開發(2)速度測試模組 基於MFC的USB上位機開發(3)資料傳輸模組 基於MFC的USB上位機開發(4)環路模組 基於MFC的USB上位機開發(5)下環路模組 目錄 1. 設計思路 1.

基於MFC的USB上位開發(2)速度測試模組

延伸閱讀: 基於MFC的USB上位機開發(1)概述 基於MFC的USB上位機開發(2)速度測試模組 基於MFC的USB上位機開發(3)資料傳輸模組 基於MFC的USB上位機開發(4)環路模組 基於MFC的USB上位機開發(5)下環路模組 目錄 1. USB裝

基於MFC的USB上位開發(1)概述

延伸閱讀: 基於MFC的USB上位機開發(1)概述 基於MFC的USB上位機開發(2)速度測試模組 基於MFC的USB上位機開發(3)資料傳輸模組 基於MFC的USB上位機開發(4)環路模組 基於MFC的USB上位機開發(5)下環路模組 目錄 1 工程準備

基於MFC的 CYPRESS USB上位除錯記錄

問題1: 1>------ 已啟動生成: 專案: USBdetect, 配置: Debug Win32 ------ 1>正在編譯... 1>USBdetectDlg.cpp 1>c:\project\usbdetect\usbdetect\usbdetectdlg.

【專題教程第8期】基於emWin模擬器的USB BULK上位開發,僅需C即可,簡單易實現

說明:1、如果你會emWin話的,就可以輕鬆製作上位機。做些通訊和控制類上位機,比使用C#之類的方便程度一點不差,而且你僅會C語言就可以。2、並且成功將emWin人性化,可以做些Windows系統上的小應用了,基本完全看不出是emWin做的,而且生成的軟體很小。Win32 API編寫的軟體,最大的好處就是微軟

C# 實現自定義的USB設備與上位進行通信(上位部分)

lob filename 參考 EDA 文件 inpu sha red file   因為以前沒用過USB,對USB也不了解,於是上網查了很多資料,不過網上的資料都是零零散散,不清不楚的,於是我自己總結了一下,下面幾個鏈接是網上這麽多零散資料裏,我覺得比較有參考意義的。  

stm32發送數據給上位用串口調試助手接收為什麽只接收到第一個字節數據?

stm32、串口調試、只接收到一個字節數據 最近剛好要做一個舵機的狀態包反饋,用串口調試助手接收調試。然後發現中斷接收數據後,將數據發送給上位機(調試助手)時只接收到了最後一個字節的數據,後來以為數據發送的太快了,然後在每個字節發送完都加了延時,結果發現只接收到第一個數據。1、 在這個過程中,通過調試我

STM32網路遠端升級韌體的IAP程式實現與解析 ---附親測穩定能用的程式

STM32網路遠端升級韌體的IAP程式實現與解析 ---附親測穩定能用的程式 http://www.openedv.com/thread-104667-1-1.html (出處: OpenEdv-開源電子網)  

C++實現串列埠通訊上位軟體

串列埠使用的是RS232匯流排進行通訊,通訊方式是半雙工。有兩種方式可以實現串列埠通訊,一種是通過ActiveX控制元件這種方法程式簡單,但欠靈活。第二個是可以通過呼叫Windows的API函式,本例程通過第二種方式。 一般通過四步來完成通訊(1)開啟串列埠(2)配置串列埠(3)讀寫串列埠(4)

Qt中Qchart外掛實現PMW3901迷你光流模組上位(串列埠通訊)

文章目錄 Qt中Qchart外掛實現PMW3901迷你光流模組上位機 光流計介紹 上位機 完整工程[猛戳這兒](https://github.com/LiangtaoZhong/PMW3901-monitor)。

[原創]python下通過modbus_tk實現modbus主機上位

如果你的開發環境是python3及以上 pip3 install modbus_tk 否則使用 pip install modbus_tk 直接貼Python程式碼 系統:win10 IDE:pycharm + Qtdesigner 目標:實現簡單modbus通訊 import

QT 正確使用hidapi庫檔案實現HID上位開發

    用QT做上位機介面通過USB與下位機通訊,採用開源庫hidapi實現HID相關功能,結果程式碼構建成功但執行時總是出現crash錯誤,而後查詢發現是.dll檔案沒有放置在debug資料夾下,這裡做一個簡單記錄。       總結下用QT呼叫hidapi庫開發HID通

C++實現上位6:網路通訊類CCommnication

CCommnication標頭檔案: #pragma once //#include "CCreateHex.h" #include "CComminicationTool.h" //#include "CEthernetTCP.h" #include "CSerialP

Eclipse中使用真進行USB除錯android程式

    在android小程式的開發過程中,使用eclipse中的虛擬機器進行程式開發速度較慢,用真機開發可以顯著提高除錯的速度。     這裡我用的作業系統是win7專業版,手機型號華為G520;   &n

USB狀態與資訊檢測”上位設計方法

1. 使用MFC新建USB上位機工程     USB晶片型號為:CYC7C68013A,上位機的開發環境為Visual Studio 2008,工程檔案由MFC嚮導生成,具體步驟如下: (1)開啟VS2008,依次單擊 檔案 -> 新建 -> 專案,選單中專案

微信小程式實現轉發功能以及真除錯跳坑(附程式碼)

前置知識可先閱覽以下博文 https://blog.csdn.net/xiaochun365/article/details/76546585 https://blog.csdn.net/xiaochun365/article/details/76546585   先在