1.引用CyAPI.lib
2.USBCOM.h
1 #pragma once 2 3 #include <QtWidgets/QDialog> 4 #include "ui_USBCOM.h" 5 #include <Windows.h> 6 #include "cyAPI.h" 7 #include<QTimer> 8 class USBCOM : public QDialog 9 { 10 Q_OBJECT 11 12 public: 13 USBCOM(QWidget *parent = nullptr); 14 ~USBCOM(); 15 16 private: 17 Ui::USBCOMClass ui; 18 public: 19 const int USBSendDataLenth = 512; 20 char sendOut[512] = { 0 }; 21 char sendIn[512] = { 0 }; 22 CCyUSBDevice *m_usbDevice; 23 CCyUSBEndPoint *m_InEndpt; 24 CCyUSBEndPoint *m_OutEndpt; 25 OVERLAPPED outOvLap; 26 OVERLAPPED inOvLap; 27 void OnInit(); 28 QTimer *m_monitorTimer = NULL; 29 bool bStart = false; 30 unsigned short CRC16_MODBUS(unsigned char *data, unsigned int datalen); 31 private slots: 32 void OnClear(); 33 void OnStartReceive(); 34 void OnSendData(); 35 void OnSendTimer(); 36 void On2To16(); 37 };
3.USBCOM.cpp
1 #include "USBCOM.h" 2 #include<QFileDialog> 3 #include<QProcess> 4 #pragma execution_character_set("utf-8") 5 USBCOM::USBCOM(QWidget *parent) 6 : QDialog(parent) 7 { 8 ui.setupUi(this); 9 outOvLap.hEvent = CreateEvent(NULL, false, false, L"CYUSB_OUT1"); 10 //inOvLap.hEvent = CreateEvent(NULL, false, false, L"CYUSB_IN1"); 11 OnInit(); 12 13 connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(OnSendData())); 14 connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(OnStartReceive())); 15 connect(ui.pushButton_3, SIGNAL(clicked()), this, SLOT(OnClear())); 16 connect(ui.pushButton_4, SIGNAL(clicked()), this, SLOT(OnSendTimer())); 17 connect(ui.pushButton_5, SIGNAL(clicked()), this, SLOT(On2To16())); 18 19 if (m_monitorTimer == NULL) 20 { 21 m_monitorTimer = new QTimer(this); 22 connect(m_monitorTimer, &QTimer::timeout, [=]() { 23 OnSendTimer(); 24 }); 25 } 26 setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); 27 this->setWindowState(Qt::WindowMaximized); //最大化 28 ui.pushButton_4->setVisible(false); 29 30 } 31 32 USBCOM::~USBCOM() 33 { 34 CloseHandle(outOvLap.hEvent); 35 CloseHandle(inOvLap.hEvent); 36 m_usbDevice->Close(); 37 } 38 void USBCOM::OnInit() 39 { 40 bool bOK = false; 41 m_usbDevice = new CCyUSBDevice((HANDLE)this->winId());//裝置控制類 42 int devices = m_usbDevice->DeviceCount();//返回連線在USB匯流排上的USB個數 43 if (devices > 0) 44 { 45 for (int i = 0; i < devices; i++) 46 { 47 m_usbDevice->Open(i);//開啟USB裝置 48 if (!m_usbDevice->IsOpen())//檢查是否獲得USB裝置控制代碼並啟動了該裝置 49 { 50 continue; 51 } 52 53 USB_CONFIGURATION_DESCRIPTOR ConfDesc; 54 m_usbDevice->GetConfigDescriptor(&ConfDesc);//獲取當前裝置配置描述符 55 56 if (ConfDesc.bNumInterfaces == 1)//該配置所支援的介面數 57 { 58 USB_INTERFACE_DESCRIPTOR IntfDesc; 59 m_usbDevice->GetIntfcDescriptor(&IntfDesc);//獲取當前選擇的介面描述符 60 61 if (IntfDesc.bAlternateSetting == 0 62 && IntfDesc.bNumEndpoints == 4)//可替換設定值 USB介面所使用的埠總數 63 { 64 int iVID = m_usbDevice->VendorID;//裝置描述符iDVendor域的值=供應商ID 65 int iPID = m_usbDevice->ProductID;//裝置描述符iProduct域的值=產品ID 66 67 QString VID = QString("%1").arg(iVID, 4, 16, QLatin1Char('0')); 68 QString PID = QString("%1").arg(iPID, 4, 16, QLatin1Char('0')); 69 70 GUID _guid = m_usbDevice->DriverGUID();//返回USB驅動的GUID值 71 72 wchar_t *c = m_usbDevice->SerialNumber;//裝置描述符iSerialNumber 序列號字串描述符的索引值 73 QString SerialNumber = QString::fromWCharArray(c); 74 if(SerialNumber=="B2464C79-79BA-479D-8948-301AF20EA4EA") 75 { 76 CCyUSBEndPoint *endpt;//傳輸 77 int epts = m_usbDevice->EndPointCount();//當前介面的端點數(包括0埠) 78 79 for (int j = 1; j < epts; j++) 80 { 81 endpt = m_usbDevice->EndPoints[j];//端點列表 82 83 if (endpt->Attributes == 2)//端點描述符-端點特性-塊bulk傳輸 84 { 85 char s[12]; 86 sprintf(s, "0x%02X", endpt->Address);//端點號 傳輸方向 第7位 0:OUT 1:In;3~0位:端點 87 88 if (endpt->Address & 0x80)//0x8_輸入 0x0_輸出 89 { 90 if (0 == QString::compare(QString(s), "0x86", Qt::CaseInsensitive))//端點6輸入 91 { 92 m_InEndpt = endpt; 93 bOK = true; 94 } 95 } 96 else 97 { 98 if (0 == QString::compare(QString(s), "0x02", Qt::CaseInsensitive))//端點2輸出 99 { 100 m_OutEndpt = endpt; 101 bOK = true; 102 } 103 } 104 } 105 } 106 } 107 108 } 109 } 110 } 111 } 112 113 } 114 void USBCOM::OnClear() 115 { 116 ui.plainTextEdit_2->clear(); 117 118 } 119 void USBCOM::OnStartReceive() 120 { 121 bStart = !bStart; 122 if (bStart) 123 { 124 m_monitorTimer->start(200); 125 ui.pushButton->setText("停止接收"); 126 } 127 else 128 { 129 m_monitorTimer->stop(); 130 ui.pushButton->setText("開始接收"); 131 } 132 133 } 134 void USBCOM::OnSendTimer() 135 { 136 LONG len1 = USBSendDataLenth; 137 m_InEndpt->TimeOut = 100; 138 bool bResult = m_InEndpt->XferData((PUCHAR)sendIn, len1); 139 if(bResult) 140 { 141 QString text = QByteArray((char*)sendIn,512).toHex(); 142 ui.plainTextEdit_2->appendPlainText(text); 143 } 144 return; 145 146 //OnSendData(); 147 148 m_InEndpt->SetXferSize(USBSendDataLenth); 149 150 if ( m_InEndpt->NtStatus==0 )//& m_InEndpt->bytesWritten != 0 & m_InEndpt->LastError != ERROR_IO_PENDING) 151 { 152 memset(sendIn, 0, USBSendDataLenth); 153 UCHAR *inContext = m_InEndpt->BeginDataXfer((PUCHAR)sendIn, USBSendDataLenth, &inOvLap); 154 m_InEndpt->WaitForXfer(&inOvLap, 100); 155 LONG len = USBSendDataLenth; 156 bool success_Receive = m_InEndpt->FinishDataXfer((PUCHAR)sendIn, len, &inOvLap, inContext); 157 if (success_Receive) 158 { 159 QString text = QByteArray((char*)sendIn).toHex(); 160 ui.plainTextEdit_2->appendPlainText(text); 161 } 162 } 163 } 164 165 void USBCOM::OnSendData() 166 { 167 QString sendData = ui.plainTextEdit->toPlainText(); 168 169 memset(sendOut, 0, USBSendDataLenth); 170 171 int index = 0; 172 for (int i = 0; i < sendData.size(); i = i + 2) 173 { 174 bool bOK; 175 sendOut[index] = sendData.mid(i, 2).toInt(&bOK, 16); 176 index++; 177 } 178 unsigned char data[2]; 179 unsigned short crc = CRC16_MODBUS((unsigned char *)sendOut, index); 180 sendOut[index] = crc&0XFF; 181 sendOut[index+1] = crc>>8; 182 QString a = QString("%1%2").arg(crc & 0XFF, 2, 16).arg(crc >> 8, 2, 16); 183 ui.lineEdit->setText(QString("%1%2").arg(crc & 0XFF,2,16).arg(crc >> 8, 2, 16)); 184 m_OutEndpt->SetXferSize(USBSendDataLenth); 185 //memset(&outOvLap, 0, sizeof(OVERLAPPED)); 186 //if (m_OutEndpt->LastError != ERROR_IO_PENDING) 187 { 188 UCHAR *outContext = m_OutEndpt->BeginDataXfer((PUCHAR)sendOut, USBSendDataLenth, &outOvLap);//端點非同步資料傳輸 189 m_OutEndpt->WaitForXfer(&outOvLap, 100);//等待非同步通訊傳輸結束 190 LONG len = USBSendDataLenth; 191 bool success_Send = m_OutEndpt->FinishDataXfer((PUCHAR)sendOut, len, &outOvLap, outContext);//非同步資料傳輸儲存 192 if (!success_Send) 193 { 194 ui.plainTextEdit_2->appendPlainText("傳送失敗"); 195 } 196 else 197 { 198 QString text = QByteArray((char*)outContext).toHex(); 199 ui.plainTextEdit_2->appendPlainText("傳送成功"); 200 } 201 } 202 //else 203 //{ 204 // m_OutEndpt->Abort(); 205 // m_OutEndpt->Reset(); 206 //} 207 208 } 209 210 //CRC16 211 unsigned short USBCOM::CRC16_MODBUS(unsigned char *data, unsigned int datalen) 212 { 213 unsigned short wCRCin = 0xFFFF; 214 unsigned short wCPoly = 0xA001; 215 216 217 while (datalen--) 218 { 219 wCRCin ^= *(data++); 220 for (int i = 0; i < 8; i++) 221 { 222 if (wCRCin & 0x01) 223 wCRCin = (wCRCin >> 1) ^ wCPoly; 224 else 225 wCRCin = wCRCin >> 1; 226 } 227 } 228 return (wCRCin); 229 } 230 231 //2進位制轉16進位制 232 void USBCOM::On2To16() 233 { 234 QString qstrFilePath; 235 qstrFilePath = QFileDialog::getOpenFileName(this, "開啟訊號線in檔案", ".\\", "*.in"); 236 if (qstrFilePath.isEmpty()) 237 { 238 return; 239 } 240 QFile qFile(qstrFilePath); 241 if (!qFile.open(QIODevice::ReadOnly | QIODevice::Text)) 242 return; 243 QFile qFileTxt(qstrFilePath.left(qstrFilePath.length()-2)+"txt"); 244 if (!qFileTxt.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) 245 return; 246 247 do 248 { 249 QString qstrTemp = qFile.readLine().trimmed(); 250 251 qstrTemp.replace('.','0'); 252 qstrTemp.replace(':', ':'); 253 //const QRegExp QRegExp_IN("^J[0-9]{3}:[0-1]+$"); 254 //if (!QRegExp_IN.exactMatch(qstrTemp)) 255 // return; 256 257 258 if (qstrTemp.indexOf(":")!=-1) 259 { 260 QStringList qStringList = qstrTemp.split(':'); 261 QString qstr0 = qStringList[0].trimmed(); 262 //qstr0 = qstr0.remove(0, 1); 263 qFileTxt.write(QString(qstr0 + ":").toLatin1()); 264 QString qstr1 = qStringList[1].trimmed(); 265 int size = ceil(qstr1.size() / 8.0); 266 267 for (int i = 0; i < size; i++) 268 { 269 QByteArray bastr = qstr1.mid(i * 8, 8).toLatin1(); 270 bool bOK; 271 int data = bastr.toInt(&bOK, 2); 272 QString aa = QString("%1").arg(data,2,16, QLatin1Char('0')); 273 qFileTxt.write(aa.toLatin1()); 274 } 275 } 276 qFileTxt.write("\n"); 277 } while (!qFile.atEnd()); 278 279 qFile.close(); 280 qFileTxt.close(); 281 QProcess::startDetached("C:\\Windows\\system32\\notepad.exe", { qstrFilePath.left(qstrFilePath.length() - 2) + "txt" }); 282 }
4.介面