Qt_USB-HID_timer.pro
#-------------------------------------------------
#
# Project created by QtCreator 2020-02-26T15:36:22
#
#-------------------------------------------------
QT += core gui
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Qt_USB-HID_demo
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
LIBS += -L$$_PRO_FILE_PWD_/ -lhidapi
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include "hidapi.h"
#include
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QByteArray HexStringToByteArray(QString HexString);
QString ByteArrayToHexString(QByteArray data);
void Receive_USBHID_message();
private slots:
void on_pushButton_detectusb_clicked();
void on_pushButton_usblock_clicked();
void on_comboBox_usbhid_currentTextChanged();
void on_pushButton_ClearSend_clicked();
void on_pushButton_ClearReceive_clicked();
void on_checkBox_HexReceive_clicked();
void on_checkBox_HexSend_clicked();
void on_pushButton_HIDSend_clicked();
private:
Ui::MainWindow *ui;
/*usbhid*/
hid_device *handle;
unsigned short vendor_id;
unsigned short product_id;
bool USBHID_Rev_Enable;
unsigned char usb_data[65];
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("USB-HID 发送与接收64Byte");
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton_HIDSend->setEnabled(false);
ui->checkBox_HexReceive->setCheckState(Qt::Checked);
ui->checkBox_HexSend->setCheckState(Qt::Checked);
ui->checkBox_HexReceive->setEnabled(false);
USBHID_Rev_Enable = false;
QTimer *timer1 = new QTimer(this);
connect(timer1, &QTimer::timeout, this, &MainWindow::Receive_USBHID_message);
timer1->start(10);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_detectusb_clicked()
{
hid_init();
struct hid_device_info * P_device;
P_device = hid_enumerate(0, 0);
//清空usbhid设备框
ui->comboBox_usbhid->clear();
if(P_device != NULL)
statusBar()->showMessage("检测到USBHID设备",3000);
while(P_device != NULL)
{
ui->comboBox_usbhid->addItem(QString::fromWCharArray(P_device->product_string));
P_device = P_device->next;
}
hid_free_enumeration(P_device);
hid_exit();
}
void MainWindow::on_pushButton_usblock_clicked()
{
char s[100];
if(ui->pushButton_usblock->text()==QString("打开"))
{
hid_init();
struct hid_device_info * P_device;
P_device = hid_enumerate(0, 0);
while(P_device != NULL)
{
if((ui->comboBox_usbhid->currentText()) == (QString::fromWCharArray(P_device->product_string)))
{
this->vendor_id = P_device->vendor_id;
this->product_id = P_device->product_id;
break;
}
P_device = P_device->next;
}
//已经获得选中项的vid&pid,释放设备链表
hid_free_enumeration(P_device);
this->handle = hid_open(this->vendor_id , this->product_id, NULL);
if(NULL != this->handle)
{
USBHID_Rev_Enable = true;
qDebug("成功打开vid=0x%04x,pid=0x%04x 的usbhid设备!", this->vendor_id, this->product_id);
sprintf(s,"成功打开vid=0x%04x,pid=0x%04x 的usbhid设备!", this->vendor_id, this->product_id);
statusBar()->showMessage(QString(s),3000);
ui->pushButton_usblock->setText(QString("关闭")); //usb进入打开状态
//在界面显示vid和pid
char s[40];
sprintf(s,"VID:0x%04X", this->vendor_id);
QString vid_str = s;
ui->label_vid->setText(vid_str);
sprintf(s,"PID:0x%04X", this->product_id);
QString pid_str = s;
ui->label_pid->setText(pid_str);
//以下控件失效
ui->pushButton_detectusb->setEnabled(false);
ui->comboBox_usbhid->setEnabled(false);
//以下控件使能
ui->pushButton_HIDSend->setEnabled(true);
}else
{
qDebug("打开vid=0x%04x,pid=0x%04x 的usbhid设备失败!", this->vendor_id, this->product_id);
sprintf(s,"打开vid=0x%04x,pid=0x%04x 的usbhid设备失败!", this->vendor_id, this->product_id);
statusBar()->showMessage(QString(s),3000);
return;
}
}
else
{
hid_close(this->handle);
USBHID_Rev_Enable = false;
qDebug("成功关闭vid=0x%04x,pid=0x%04x 的usbhid设备!", this->vendor_id, this->product_id);
sprintf(s,"成功关闭vid=0x%04x,pid=0x%04x 的usbhid设备!", this->vendor_id, this->product_id);
statusBar()->showMessage(QString(s),3000);
hid_exit();
ui->pushButton_usblock->setText(QString("打开")); //usb进入关闭状态
QString vid_str = "VID:";
QString pid_str = "PID:";
ui->label_vid->setText(vid_str);
ui->label_pid->setText(pid_str);
//以下控件使能
ui->pushButton_detectusb->setEnabled(true);
ui->comboBox_usbhid->setEnabled(true);
//以下控件失效
ui->pushButton_HIDSend->setEnabled(false);
}
}
void MainWindow::on_comboBox_usbhid_currentTextChanged()
{
hid_init();
struct hid_device_info * P_device;
P_device = hid_enumerate(0, 0);
while(P_device != NULL)
{
if((ui->comboBox_usbhid->currentText()) == (QString::fromWCharArray(P_device->product_string)))
{
this->vendor_id = P_device->vendor_id;
this->product_id = P_device->product_id;
break;
}
P_device = P_device->next;
}
//已经获得选中项的vid&pid,释放设备链表
hid_free_enumeration(P_device);
char s[100];
sprintf(s,"VID:0x%04X", this->vendor_id);
QString vid_str = s;
ui->label_vid->setText(vid_str);
sprintf(s,"PID:0x%04X", this->product_id);
QString pid_str = s;
ui->label_pid->setText(pid_str);
sprintf(s,"设备属性:vid=0x%04x,pid=0x%04x", this->vendor_id, this->product_id);
statusBar()->showMessage(QString(s),3000);
}
void MainWindow::on_pushButton_ClearSend_clicked()
{
ui->textEdit_send->clear();
statusBar()->showMessage("清空发送区成功",3000);
}
void MainWindow::on_pushButton_ClearReceive_clicked()
{
ui->textEdit_receive->clear();
statusBar()->showMessage("清空接收区成功",3000);
}
void MainWindow::on_checkBox_HexReceive_clicked()
{
if(ui->checkBox_HexReceive->isChecked()==true)
{
qDebug("以16进制显示");
statusBar()->showMessage("以16进制显示",3000);
}else if(ui->checkBox_HexReceive->isChecked()==false)
{
qDebug("取消以16进制显示");
statusBar()->showMessage("取消以16进制显示",3000);
}
}
void MainWindow::on_checkBox_HexSend_clicked()
{
if(ui->checkBox_HexSend->isChecked()==true)
{
qDebug("以16进制发送");
statusBar()->showMessage("以16进制发送",3000);
}else if(ui->checkBox_HexSend->isChecked()==false)
{
qDebug("取消以16进制发送");
statusBar()->showMessage("取消以16进制发送",3000);
}
}
/*
* @breif 将16进制字符串转换为对应的字节序列
*/
QByteArray MainWindow::HexStringToByteArray(QString HexString)
{
bool ok;
QByteArray ret;
HexString = HexString.trimmed();
HexString = HexString.simplified();
QStringList sl = HexString.split(" ");
foreach (QString s, sl) {
if(!s.isEmpty())
{
char c = s.toInt(&ok,16)&0xFF;
if(ok){
ret.append(c);
}else{
qDebug()<<"非法的16进制字符:"<<s;
QMessageBox::warning(0,tr("错误:"),QString("非法的16进制字符: \"%1\"").arg(s));
}
}
}
//qDebug()<
return ret;
}
/*
* @breif 将字节序列转换为对应的16进制字符串
*/
QString MainWindow::ByteArrayToHexString(QByteArray data){
QString ret(data.toHex().toUpper());
int len = ret.length()/2;
qDebug()<<len;
for(int i=1;i<len;i++)
{
//qDebug()<
ret.insert(2*i+i-1," ");
}
return ret;
}
void MainWindow::Receive_USBHID_message()
{
if(USBHID_Rev_Enable)
{
int res = hid_read_timeout(this->handle, usb_data, 64, 1);
if(res>0)
{
QDateTime time = QDateTime::currentDateTime();
QString time_qstr = time.toString("yyyy-MM-dd hh:mm:ss");
QString qstr = "接收时间:"+time_qstr+"\r\n----------------------\r\n";
for(int i=0; i<64; i++)
{
qstr += QString(QByteArray((char *)&usb_data[i],1).toHex()).toUpper();
qstr += " ";
}
qstr = qstr + "\r\n\r\n" + ui->textEdit_receive->toPlainText() ;
ui->textEdit_receive->setText(qstr);
statusBar()->showMessage("USBHID收到新数据! "+time_qstr,3000);
}
}
}
void MainWindow::on_pushButton_HIDSend_clicked()
{
unsigned char usb_data[65];
char s[100];
//获取界面上的数据并转换成utf8格式的字节流
QString sendMsg = ui->textEdit_send->toPlainText();
QByteArray data = sendMsg.toLatin1();
//如果以16进制发送
if(ui->checkBox_HexSend->isChecked() == true)
{
data = HexStringToByteArray(sendMsg);
}
for(int i=1; i<65; i++)
{
if(i<data.length()+1)
usb_data[i]=data.data()[i-1];
else
usb_data[i]=0xff;
}
int res = hid_write(this->handle, usb_data, 65); //至少写入64字节,协议64字节,第一个字节作废
qDebug("写入结果res = %d", res);
if(-1 == res)
{
qDebug("USBHID写入字节错误!");
statusBar()->showMessage("USBHID写入字节错误!",3000);
return;
}
else
{
qDebug("USBHID写入成功,实际写入了 %d 个字节!", res-1);
sprintf(s,"USBHID写入成功,实际写入了 %d 个字节!", res-1);
statusBar()->showMessage(QString(s),3000);
}
}
相关链接:
1.STM32CubeMX实现STM32 USBHID双向64字节通信(下位机部分)
2.STM32CubeMX实现STM32 USBHID双向64字节通信(下位机部分)源代码
3.Qt_USB-HID_timer 源代码