USB-CyAPI

wuyuan2011woaini發表於2024-05-14

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.介面