1.首先需要遍歷注冊表得到所有可用的串口
將得到的每一個串口保存到向量vector中,代碼如下:
// 得到所有的串口號 vector<string> cnComm::getComPort() { HKEY hKey; char portName[256], commName[256]; // 打開串口注冊表對應的鍵值 if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm", NULL, KEY_READ, &hKey)) { int i = 0; int mm = 0; DWORD dwLong, dwSize; while (TRUE) { dwLong = dwSize = sizeof(portName); // 枚舉串口 if (ERROR_NO_MORE_ITEMS == ::RegEnumValue(hKey, i, portName, &dwLong, NULL, NULL, (PUCHAR)commName, &dwSize)) { break; } comName.push_back(commName); i++; } // 關閉注冊表 RegCloseKey(hKey); } else { MessageBox(NULL,"您的計算機的注冊表上沒有HKEY_LOCAL_MACHINE:Hardware\\DeviceMap\\SerialComm項","警告",MB_OK); } // 返回串口號 return comName; }
2.串口的自動識別
硬件開發時,就事先規定通信的協議,然后再依次將得到的串口號打開,向串口中寫入事先規定好的字符,這里是“CHECKCONNECT”,如果沒有得到事先規定的返回值,則通信失敗,關閉串口,並打開下一個串口,如果得到規定的“OK”就代表通信成功,識別串口成功。詳細的代碼如下所示:
// 自動識別串口 bool cnComm::OnCommunicate() { int port_index; // 遍歷當前可用的串口號 for (int i = 0; i < comName.size(); ++i) { cnComm(); // 初始化通信標志 IsCommflag = false; // 得到串口號的ID,因為得到的是ASCII碼,要將其轉化到十進制 port_index = comName[i][comName[i].size() - 1] - '0'; // 依次打開可用的串口號 Open(port_index, "115200,n,8,1"); // 寫入連接檢查的數據 char* Data = "CHECKCONNECT"; Write((const char *)Data); // 開辟20個字節的地址,初始化為0 char p[20] = { 0 }; // 從緩沖區當中得到數據,首先要考慮延時的問題,所以這里睡眠100毫秒 Sleep(100); char* aa = ReadString(p, 16, 300); // 如果返回的數據中的前兩個字節是“OK”,則表示通信成功 if (strncmp("OK", aa, 2) == 0) { IsCommflag = true; //MessageBox(NULL, "通信成功", "提示", MB_OK); return true; } else // 否則通信不成功 { IsCommflag = false; // 關閉串口,同時也關閉關聯線程 Close(); } } return IsCommflag; }