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; }