码迷,mamicode.com
首页 > Windows程序 > 详细

Auto Seeking USB Com Port in Windows

时间:2015-06-07 09:33:13      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:serial   windows   


    After you read previous article, I might know how to operate a com port in Windows.

   But that example requires programmer (or user, if you modified that example being able to support inputting command line) to set a com port number, it is not consummate. I will fill the flaw in here.


You need to check the device enumeration path zeroth. In here, I use CH340 (USB com port chip from China)


技术分享



 You need to set hSerial as invalid in the begining of that code:


hSerial = INVALID_HANDLE_VALUE;

And you should replace that as the code below:

 hSerial = CreateFile(&comPortName[0], GENERIC_READ|GENERIC_WRITE, 0, NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
as


 if(0 == strncmp(&comPortName[0], "\\\\.\\COM0", MAX_STR_LEN))
 {  
  unsigned int i;

  COMMCONFIG comConfig;
  DWORD dwSize;   
  dwSize = sizeof(comConfig);


  ZeroMemory(&comConfig, sizeof(COMMCONFIG));
  
  for(i = 1; i< 256; i++){
   TCHAR comName[16];

   sprintf(&comName[0], "COM%d", i);

   if(FALSE != GetDefaultCommConfig(&comName[0], &comConfig, &dwSize))
    printf("found %s\n", &comName[0]);
  }/*for */

 }


 if(0 == strncmp(&comPortName[0], "\\\\.\\COM0", MAX_STR_LEN))
 {    
  DWORD dwGuids;
  GUID *pGuids;  

  HDEVINFO hDevInfo; 
  SP_DEVICE_INTERFACE_DATA devInterfaceData; 
  SP_DEVINFO_DATA devInfoData;
  unsigned int index;

  dwGuids = 0;
  

  isSuc = SetupDiClassGuidsFromName("Ports", NULL, 0, &dwGuids);
  

  pGuids = (GUID*)malloc(dwGuids*sizeof(GUID));
  ZeroMemory(pGuids, dwGuids*sizeof(GUID));
  isSuc = SetupDiClassGuidsFromName("Ports", pGuids, dwGuids, &dwGuids);
    
  hDevInfo = SetupDiGetClassDevs(pGuids, NULL, NULL, 
  /*DIGCF_ALLCLASSES | DIGCF_PRESENT |*/ DIGCF_DEVICEINTERFACE);  
  
  index = 0;

  ZeroMemory(&devInfoData, sizeof(SP_DEVINFO_DATA));  
  devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

 
        while(SetupDiEnumDeviceInfo(hDevInfo, index, &devInfoData))
  {   

   TCHAR szDeviceInstanceID[1024];            

   index++;

   isSuc = CM_Get_Device_ID(devInfoData.DevInst, 
     &szDeviceInstanceID[0] , sizeof(szDeviceInstanceID), 0);
   
   //printf("%s\n", &szDeviceInstanceID[0]);

   if(0 == strncmp(&szDeviceInstanceID[0], "USB\\VID_1A86&PID_7523", 
    strlen("USB\\VID_1A86&PID_7523")) )
   {
        
    DWORD requiredSize;
    GUID classGuid;

    SP_DEVICE_INTERFACE_DATA   devInterfaceData;   
    SP_DEVICE_INTERFACE_DETAIL_DATA *pDevInterfaceDetailData;

    printf("&szDeviceInstanceID[0] = %s\n", &szDeviceInstanceID[0]);

    ZeroMemory(&devInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); 
         
    devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 
    classGuid = devInfoData.ClassGuid;

    isSuc = SetupDiEnumDeviceInterfaces(hDevInfo, &devInfoData, pGuids,
     0, &devInterfaceData);    

    
    isSuc = SetupDiGetDeviceInterfaceDetail(hDevInfo, 
     &devInterfaceData, NULL, NULL, &requiredSize, NULL);

    //printf ("%s\n", GetLastErrorMessage( GetLastError() ) );

    pDevInterfaceDetailData = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(requiredSize);       

    pDevInterfaceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

    isSuc = SetupDiGetDeviceInterfaceDetail( hDevInfo, 
     &devInterfaceData, pDevInterfaceDetailData, requiredSize,
     &requiredSize, &devInfoData);

    
    printf("devInterfaceDetailData.DevicePath = %s\n", 
     pDevInterfaceDetailData->DevicePath);

    hSerial = CreateFile(pDevInterfaceDetailData->DevicePath, 
     GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 
     FILE_ATTRIBUTE_NORMAL, NULL );
    
    free(pDevInterfaceDetailData); pDevInterfaceDetailData = NULL;

    if(INVALID_HANDLE_VALUE != hSerial)
     break;
   }
  }           
  
  free(pGuids); pGuids = NULL;
  SetupDiDestroyDeviceInfoList(hDevInfo);

  if(INVALID_HANDLE_VALUE == hSerial)
  {
   printf("auto seeking com number fail!!\n");
   return 0;
  }
 }
 else /*non auto seeking com port*/ 
 {
  hSerial = CreateFile(&comPortName[0], GENERIC_READ | GENERIC_WRITE, 
   0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
 }/*if auto seeking com port*/

("\\\\.\\COM0" be  auto-seeking mode in here.)
  
You have to modify the USB\\VID_1A86&PID_7523 as your device‘s.

( If you use FTDI‘s FT232B  or FT232R, that should be

FTDIBUS\\VID_0403+PID_6001

技术分享

)




That would support auto-seeking com-port.

Note the line :


        while(SetupDiEnumDeviceInfo(hDevInfo, index, &devInfoData))
  
You would find NOT ONLY one device as VID_1A86&PID_7523, even you have plugged only one CH340. If you print that seeking result (it is just the line : printf("&szDeviceInstanceID[0] = %s\n", &szDeviceInstanceID[0]);), you would watch the printing as:


&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&1
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&1#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&2
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&2#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&3
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&3#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&4
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&4#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\6&123E8975&0&5
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#6&123e8975&0&5#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\7&107B0B49&0&2
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#7&107b0b49&0&2#{4d
36e978-e325-11ce-bfc1-08002be10318}
&szDeviceInstanceID[0] = USB\VID_1A86&PID_7523\7&14F85601&0&1
devInterfaceDetailData.DevicePath = \\?\usb#vid_1a86&pid_7523#7&14f85601&0&1#{4d
36e978-e325-11ce-bfc1-08002be10318}

I do not know why Windows lists so much device path. AlI I could do, is to try opening each. you could find that the actual one‘s last 4 characters (like &0&4, &0&2..etc) would change with port number, that depends on which USB socket you plug.


Auto Seeking USB Com Port in Windows

标签:serial   windows   

原文地址:http://blog.csdn.net/u013606170/article/details/46397879

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!