日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

在串口通信開發(fā)中實(shí)現(xiàn)自動(dòng)查找串口端口的方法

 落水成花 2015-05-02

開發(fā)工具:visual studio 2010
本機(jī)可用串口信息如下:

在串口通信開發(fā)中實(shí)現(xiàn)自動(dòng)查找串口端口的方法 - danshiming - danshiming的博客

 1 、查詢注冊表
查詢注冊表的方法是比較常見的方法,通過查看“ HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM ”項(xiàng)來獲取串口信息。該方法就是使用編程方法讀取注冊表內(nèi)信息,相當(dāng)于用戶通過在運(yùn)行框內(nèi)輸入 ”regedit” (或 regedit32 )直接打開注冊表。源代碼如下:
/************************************************************************\
* 函數(shù)說明:獲取本機(jī)所有的串口。多個(gè)串口以“|”連接。
* 參數(shù)說明:
* 返 回 值:
* 注意事項(xiàng):本方法通過從注冊表中搜索串口設(shè)備。該方法在 1ms內(nèi)即可完成查找;
                    同時(shí)也可解決 usb 轉(zhuǎn)串口設(shè)備的問題,比較實(shí)用,唯一缺點(diǎn)是,如果
                    用戶在裝某些軟硬件時(shí)在注冊表中注冊了虛擬串口之類的,用此法枚舉
                   得到的該類串口實(shí)際上是不能當(dāng)串口用的。 比如:經(jīng)測試,本機(jī)注冊
                   表有串口COM3、COM5、COM6、COM12,但通過設(shè)備管理器查看只有COM5、
                   COM6、COM12串口,沒有COM3,COM3可能是裝某些軟硬件時(shí)在注冊表中注
                   冊了虛擬串口之類的,引起的誤判。


* 編輯日期:2013-08-26 16:22:57
* 作    者:DanSir

\************************************************************************/
wstring CSerialTools::GetLocalSerial()
{
 wstring szTotalSerial;
 HKEY hKey;
 wstring szData_Set = _T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\");
 long ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szData_Set.c_str(), 0, KEY_READ, &hKey); // 打開一個(gè)制定的注冊表鍵,成功返回ERROR_SUCCESS即“0”值
 if(ret0 != ERROR_SUCCESS)
  return szTotalSerial;
 
 WCHAR szName[25] = {0};
 UCHAR szPortName[25] = {0};
 DWORD dwIndex = 0;
 DWORD dwName;
 DWORD dwSizeofPortName;
 DWORD dwType;
 LONG lStatus = -1;
 wchar_t szSerialName[256] = {0};
 dwName = sizeof(szName);
 dwSizeofPortName = sizeof(szPortName);
 do
 {
  memset(szName, 0, sizeof(szName));
        memset(szPortName, 0, sizeof(szPortName));
  lStatus = RegEnumValue(hKey, dwIndex++, szName, &dwName, NULL, &dwType, szPortName, &dwSizeofPortName);// 讀取鍵值
  DWORD dwError = GetLastError();
  if((lStatus == ERROR_SUCCESS)||(lStatus == ERROR_MORE_DATA))
  {
   memset(szSerialName, 0, sizeof(szSerialName));
   memcpy(szSerialName, szPortName, dwSizeofPortName);
   szTotalSerial += szSerialName;       // 串口字符串保存
   szTotalSerial.append(_T("|"));
  }
  // 每讀取一次dwName和dwSizeofPortName都會(huì)被修改
  // 注意一定要重置,否則會(huì)出現(xiàn)很離奇的錯(cuò)誤,本人就試過因沒有重置,出現(xiàn)先插入串口號(hào)大的(如COM4),再插入串口號(hào)小的(如COM3),此時(shí)雖能發(fā)現(xiàn)兩個(gè)串口,但都是同一串口號(hào)(COM4)的問題,同時(shí)也讀不了COM大于10以上的串口
  dwName = sizeof(szName);
  dwSizeofPortName = sizeof(szPortName);
 } while((lStatus != ERROR_NO_MORE_ITEMS));

 RegCloseKey(hKey);
 wstring::size_type nIndex = szTotalSerial.rfind(_T("|"));
 if(wstring::npos != nIndex)
 {
  szTotalSerial = szTotalSerial.substr(0, nIndex);
 }
  

 return szTotalSerial;
}
界面顯示信息如下:

在串口通信開發(fā)中實(shí)現(xiàn)自動(dòng)查找串口端口的方法 - danshiming - danshiming的博客
可以看到,從注冊表中讀出了COM3,但是COM3在設(shè)備管理器中是不存在的,所以用這種方法有誤判可能性。該方法在 1ms內(nèi)即可完成查找;同時(shí)也可解決 usb 轉(zhuǎn)串口設(shè)備的問題,比較實(shí)用,唯一缺點(diǎn)是,如果用戶在裝某些軟硬件時(shí)在注冊表中注冊了虛擬串口之類的,用此法枚舉得到的該類串口實(shí)際上是不能當(dāng)串口用的,如本例中的COM3。
2、使用 SetupAPI 函數(shù)集的方法
此種方法是最簡單的方法,之所以簡單是因?yàn)橐呀?jīng)有人將復(fù)雜的代碼封裝起來了,只需像傻子一樣調(diào)用就可以完成工作了,具體的說明請(qǐng)看 http://www./Cpp/W-P/system/hardwareinformation/article.php/c5721/ ,使用該方法要在你的程序中,添加“ EnumSerial.cpp ”和“ EnumSerial.h ”兩個(gè)文件,并且將 Setupapi.lib 包含進(jìn)你的工程,方法在項(xiàng)目屬性-配置屬性-連接器-輸入-附加依賴項(xiàng)中添加setupapi.lib,然后在EnumSerial.cpp中添加包含"setupapi.h" ,你的應(yīng)用程序添加包含EnumSerial.h頭文件就行了,
下面給出調(diào)用該方法的例子代碼:
/************************************************************************\
* 函數(shù)說明:獲取本機(jī)所有的串口。多個(gè)串口以“|”連接。
* 參數(shù)說明:
* 返 回 值:
* 注意事項(xiàng):此種方法是最簡單的方法,之所以簡單是因?yàn)橐呀?jīng)有人將復(fù)雜的代碼封裝起來了
   ,只需像傻子一樣調(diào)用就可以完成工作了,具體的說明請(qǐng)看
   http://www./Cpp/W-P/system/hardwareinformation/article.php/c5721/ ,
   使用該方法要在你的程序中,添加“ EnumSerial.cpp ”和“ EnumSerial.h ”兩個(gè)文件,
   并且將 Setupapi.lib 包含進(jìn)你的工程,方法在項(xiàng)目屬性-配置屬性-連接器-輸入-附加依賴項(xiàng)
   中添加setupapi.lib,然后在EnumSerial.cpp中添加包含"setupapi.h" ,你的應(yīng)用程序添
   加包含EnumSerial.h頭文件就行了。本方法避免了用戶在裝某些軟硬件時(shí)在注冊表中注冊了
   虛擬串口之類的東西引起的誤判。比如::經(jīng)測試,本機(jī)注冊表有串口COM3、COM5、COM6、COM12,
   但通過設(shè)備管理器查看,只有COM5、COM6、COM12串口,沒有COM3,COM3可能是裝某些軟硬件時(shí)在注
   冊表中注冊了虛擬串口之類的,如果采用讀注冊表即GetLocalSerial()方法,會(huì)將COM3也讀取到,
   從而引起的誤判,但采用本方法時(shí)則不會(huì)引起誤判,即不會(huì)將COM3讀取出來。
* 編輯日期:2013-08-27 13:25:41
* 作    者:DanSir
\************************************************************************/
wstring CSerialTools::GetlocalSerialEx()
{
 CArray<SSerInfo,SSerInfo&> asi;
 // Populate the list of serial ports.
 EnumSerialPorts(asi, FALSE/*include all*/);
 wstring szTotalSerial;
 for (int ii=0; ii < asi.GetSize(); ii++)
 {
  // 注意:不能使用asi[ii].strPortName,當(dāng)串口存在時(shí),其為空(內(nèi)部代碼沒實(shí)現(xiàn))
  CString strFriendlyName = asi[ii].strFriendlyName;
  int nIndexFirst = strFriendlyName.Find(_T("("));
  int nIndexLast = strFriendlyName.ReverseFind(')');
  if (-1 == nIndexLast || -1 == nIndexFirst)
  {
   continue;
  }
  CString strPortName = strFriendlyName.Mid(nIndexFirst + 1, nIndexLast - nIndexFirst - 1);
  szTotalSerial += strPortName;       // 串口字符串保存
  szTotalSerial.append(_T("|"));
 }
 wstring::size_type nIndex = szTotalSerial.rfind(_T("|"));
 if(wstring::npos != nIndex)
 {
  szTotalSerial = szTotalSerial.substr(0, nIndex);
 }
 return szTotalSerial;
}
界面顯示如下:
在串口通信開發(fā)中實(shí)現(xiàn)自動(dòng)查找串口端口的方法 - danshiming - danshiming的博客
 
 
該方法查找一個(gè)串口就要 15ms 左右,但可以看到該方法獲取的串口完完全全就是硬件設(shè)備管理器中的串口。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多