前言:

usb 不仅仅hid通信方式,还有其余的usb通信方式,但hid的好处就是无需安装驱动,热插拔直接用,等,具体详细介绍自行百度。

目的:

此处插补一个写此文章的目的:

下位机与上位机串口通信连接不同usb接口,避免每次自动重新配置连接的串口端口号 三种方式:
1.修改下位机程序,上位机程序不变
下位机程序输出接口改为usb虚拟串口模式,硬件外设采用usb接口,参考正点原子库函数库例程(USB虚拟串口试验),这样不论usb插哪一个接口,均为同一虚拟串口。

2.下位机硬件和程序不变,上位机采用轮询连接当前设备可用串口,连接后通信测试,测试成功代表串口正确。

3.下位机硬件加上ttl转usb芯片,程序不变,上位机添加usb设备识别,即此篇文章的目的。

环境:

qt5.7 (msvc2013 32bit)

准备:

本文介绍采用hid方式,所以提供的连接都是hid的

参考链接:Qt USB通信--hidapi的使用_www.wowothink.com的博客-CSDN博客_-lhidapi

参考链接:Ubuntu/Windows下利用“HIDAPI”库函数实现与Hid类USB设备通信 - Ch_Y_Q - 博客园

下载资料链接:USBDEVICE.rar-QT工具类资源-CSDN下载

正文:

首先是qt上位机部分,我是拿的hid无线鼠标试验的,在设备管理器找到鼠标的vid和pid

已配置设备 HID\VID_1EA7&PID_0064&Col02\6&37799645&0&0001。

代码如下。hid_read函数目前不可用,使用程序就会报异常,目前只能write和获取设备一些信息,但是无法看出来实际的效果,暂时停止进展,等待用单片机做一个串口转hid usb的出来,或者单片机直接写好usb hid 的底层驱动,在具体通信实验。

记录下当前时间:2019年8月23日12:38:58

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "hidapi.h"#define MAX_STR 255//#pragma comment(lib, "D:/QT57/workspace/My/untitled1/hidapi.lib")
//#pragma comment(lib, "hidapi.lib")MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);int res;unsigned char buf[128];wchar_t wstr[MAX_STR];hid_device *handle;int i;// Open the device using the VID, PID,// and optionally the Serial number.handle = hid_open(0x1EA7, 0x0064, NULL);qDebug()<<"handle"<<handle;//目前只能写入,不能读取,等待  串口ttl转hid usb芯片到货在试验//res = hid_read(handle, buf, 128);qDebug()<<"buf0"<<buf[0];qDebug()<<"buf1"<<buf[1];// Read the Manufacturer Stringres = hid_get_manufacturer_string(handle, wstr, MAX_STR);wprintf(L"Manufacturer String: %s\n", wstr);// Read the Product Stringres = hid_get_product_string(handle, wstr, MAX_STR);wprintf(L"Product String: %s\n", wstr);// Read the Serial Number Stringres = hid_get_serial_number_string(handle, wstr, MAX_STR);wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr);// Read Indexed String 1res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);wprintf(L"Indexed String 1: %s\n", wstr);// Toggle LED (cmd 0x80). The first byte is the report number (0x0).buf[0] = 0x0;buf[1] = 0x80;res = hid_write(handle, buf, 65);// Request state (cmd 0x81). The first byte is the report number (0x0).buf[0] = 0x0;buf[1] = 0x81;res = hid_write(handle, buf, 65);//Read requested state//hid_read(handle, buf, 65);//Print out the returned buffer.for (i = 0; i < 4; i++)printf("buf[%d]: %d\n", i, buf[i]);//return 0;}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{}

2019年11月29日16:43:09补更新

距离发帖已经很久了,之前没能解决这个问题,这会趁着空闲,腾出时间抓紧时间又研究了一下这个,发现拿hid的鼠标键盘测试是不靠谱的,还是用了一个ch9326模块,串口转换usb,再用串口转ttl模块模仿下位机与电脑通讯,如图所示

这个每个模块,应该说是每个芯片 都有对应固定的vid和pid,我这个模块对应的id是0x1A86, 0xE010,加了一个线程专门接收usb数据,这个不像是串口有readyread这种中断机制可以调回调函数去处理,下面话不多说上代码

初始化:

    hid_init();//不初始化也可以。在open里会初始化qDebug()<<handle;handle = hid_open(0x1A86, 0xE010, NULL);//模块qDebug()<<handle;if(handle==0)QMessageBox::information(this, "warn", "未检测到设备,使用可能导致异常!");else{hid_set_nonblocking(handle, 1);thread1=new USB_Thread;thread1->start();connect(thread1,&USB_Thread::updateString11,this,&MainWindow::updateStr);}

发送接收:

//自动接收
void MainWindow::updateStr(QString str1)
{if(!str1.isEmpty()){ui->textEdit->setText(str1);}
}
//手动接收
void MainWindow::on_pushButton_clicked()
{qDebug("hid read start");int res;QString show_text;for(int i=0;i<32;i++)buf_IN[i]=0x0b;start_flag=true;//while (start_flag) {QCoreApplication::processEvents();res = hid_read(handle,buf_IN,32);for(int i = 0;i < 32;i++){qDebug("buf[%d]:0x%02x",i,buf_IN[i]);show_text+=tr("%1,").arg(buf_IN[i]);}ui->textEdit->setText(show_text);show_text.clear();//}
}
//手动发送
void MainWindow::on_pushButton_3_clicked()
{int res;   // 如果返回-1表示发送失败unsigned char buf[10];buf[0] = 0;   // 这就是Report IDbuf[1] = 0x0a;for(int i=0;i<10;i++)buf[2+i] = i;//QCoreApplication::processEvents();res = hid_write(handle, buf, 33);//此处必须是33或这大于一些的数字,不知为什么qDebug()<<res;
}

线程:

void USB_Thread::run()
{unsigned char rbuf[32];QString str;while (1){if(isStop)return;for(int i=0;i<32;i++)rbuf[i]=0x0b;hid_read(handle,rbuf,32);//读一包数据,判断是否有数据进来sleep(1);//此处延时不可省略,否则接收数据不完全if(rbuf[0]!=0x0b&&rbuf[31]!=0x0b){//判断包头包尾是否自己写入的while(1){for(int i = 1;i < 32;i++){//从1开始,跳过数据长度第一位str+=tr("%1,").arg(rbuf[i]);}//qDebug()<<str;for(int i=0;i<32;i++)rbuf[i]=0x0b;hid_read(handle,rbuf,32);//读一包数据,判断是否数据读取完毕,最大支持接收(32-1)*n=31*n字节数据if(rbuf[0]==0x0b&&rbuf[31]==0x0b)break;}//qDebug()<<str;emit updateString11(str);}elsestr.clear();}
}

核心的地方应该算是在线程里处理数据的地方了,在线程中,首先一直判断是否接收到数据,若接收到数据,在嵌入一层逻辑关系去判断什么时候把来的数据接收完毕,这个usb发送数据是一包一包的发送,每包发送32字节,第一字节是长度,其余31字节才是有效数据,数据不足31则补0,在读取数据前像buf里写数是为了判断是否接收到数据。理解还是很容易的,usb发送接收功能都可以实现。

结语:

经历了这么长时间的帖子,最后也算是完美收工,结贴!

资源补充:

在 配置过程中可能需要用到一些dll和其他的工具

资源如下

上面例程源码(win8+64  qt5.7):USB上下位机通信.rar-QT代码类资源-CSDN下载

图片中各项资源链接:Desktop.rar-QT工具类资源-CSDN下载

qt 之usb(hid)与单片机通信相关推荐

  1. 安卓与单片机进行usb hid通信

    安卓USB_HID通信文档 因为一直在研究stm32,需要用到usb hid通信,就研究了安卓与stm32进行usb hid通信,目前已经能进行正常通信,我这里只跟大家说一下通信时需要注意的问题. u ...

  2. CSR8675学习笔记:USB HID通信

    为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板[淘宝链接:思度科技CSR开发板]. 技术交流QQ群号:743434463 开发板会员QQ群号:725398389(凭订单号入 ...

  3. 安卓OTG 安卓转串口 安卓手机与单片机通信 USB转串口

    随着物联网发展,很多的安卓网关出现,如果安卓跟单片机结合那就非常完美了. 目前安卓手机跟单片机通信都是通过蓝牙或者wifi的方式无线通信,好处是可以分开长距离通信,但是往往使用的时候安卓板子跟单片机都 ...

  4. 单片机接usb设备不用计算机,如何利用usb转串口实现单片机和电脑的通信-与非网...

    如何利用usb转串口实现单片机和电脑的通信 1.首先,单片机和微机通信的电气标准要一致,微机串口一般是RS232电气标准,所以要加电平转换芯片,大多用MAX232,一般单片机实验板上都提供这样的标准串 ...

  5. 嵌入式linux作为hid设备,基于嵌入式系统的USB(HID)设备

    基于嵌入式系统的USB(HID)设备 目前嵌入式系统在数字化电子产品领域应用越来越广泛.随着其成本的降低,大有取代单片机的趋势. USB设备以其小巧.便携.即插即用.成本低廉等优势在当前的桌面应用中有 ...

  6. C++ MFC界面读写USB HID设备数据程序

    C++ MFC界面读写USB HID设备数据程序 发一个简单易用的界面,用来对USB HID设备(比如说游戏手柄,控制面板等)读写数据,一般情况下面板上有一些LED,可以帮助我们测试读写是否正确.另外 ...

  7. 485通信原理_上位机开发之单片机通信实践

    经常会有一些学员会问到上位机与单片机之间通信的问题,而我们经常会讲上位机与PLC之间通信,那么其实对上位机开发来说,不管是和PLC通信,还是和单片机通信,通信原理都是一样的.PLC的本质就是单片机,在 ...

  8. pythonqt4上位机开发_上位机开发之单片机通信实践(一)

    经常会有一些学员会问到上位机与单片机之间通信的问题,而我们经常会讲上位机与PLC之间通信,那么其实对上位机开发来说,不管是和PLC通信,还是和单片机通信,通信原理都是一样的.PLC的本质就是单片机,在 ...

  9. USB HID 协议

    USB HID 协议入门 转载请注明来源:cuixiaolei的技术博客 USB HID设备类的应用场合 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互 ...

最新文章

  1. 解析卷积的高速计算中的细节,一步步代码带你飞
  2. OSX unable to write 'random state'
  3. python实现冒泡排序算法的非递归版本_冒泡排序以及python代码实现(递归+非递归)...
  4. 信息学奥赛一本通C++语言——1014:与圆相关的计算
  5. oracle中update补空格lpad,Oracle lpad 函数
  6. 解决安装SQL Server 2000提示文件挂起的一般方法
  7. JSK-119 求解a到100的和【入门】
  8. endnote中科大版区别_EndNote X7
  9. 计算机桌面图片查看,在CAD看图中如何快速的打开电脑桌面上的图纸进行预览查看...
  10. COMSOL35a下载地址
  11. Office产品 “您的组织策略阻止我们为您完成此操作” 解决办法
  12. uni-app 小程序dom转img 生成海报插件Painter;解决引入网络图片真机显示空白问题;解决生成的图片模糊问题
  13. R语言绘图技巧1:二元隐函数的绘制方法
  14. [C#]LambdaTest
  15. Python编曲实践(九):如何计算并估计音乐的调性(大/小调+主音)?Krumhansl-Schmuckler调性分析算法的原理与实现
  16. 计算机网络——基础篇
  17. Linux perf: 为什么采样频率设置为99Hz而不是100Hz?
  18. 【matlab】函数meshgrid的用法详解(生成网格矩阵)和ndgrid的区别及用法
  19. VIP_OSP--基于Thrift的RPC框架的基本原理
  20. 2012年9月14日部分反编译一个被混淆过的 .net 程序的笔记

热门文章

  1. Bot console WeChat机器人
  2. 使用STM8单片机+NTC热敏电阻自制简易温度巡检仪
  3. 极限的无穷小和无穷大
  4. Unity之android Drawable数据传递以APPIcon为例
  5. 大学生java 实训总结
  6. css js html 实现滚动字幕
  7. Nexus(maven私服)介绍、安装及使用教程
  8. 计算机应用论文评语大全,硕士学位论文评语大全
  9. supervisor reload报错及恢复方法
  10. R语言中的fitted() 和 predict()