用VC对USB口的打开读写操作

来源:互联网 发布:腾讯数据挖掘笔试题 编辑:程序博客网 时间:2024/06/01 08:10

USB口的打开读写操作
程序的通用性是很好的,不同的USB只需修改不同的GUID
至于调试,你怎么调试串口程序就怎么调试USB程序,大小方面一次性发送和接受数据不大于64个字节.这个可能和USB设备有关
使用一个GUIDguidHID_1查找并打开一个USB设备
extern "C" int PASCAL SearchUSBDevice()
{
 HANDLE hUsb;
 int nCount, i, j;//标记同一设备个数
 HDEVINFO hDevInfoSet;
 BOOL bResult;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;
  
 memset(m_sysversion, 0, 20);
 GetSysVersion(m_sysversion);
 // 检索相关GUID的USB设备总设备个数
 if (!GetUSBList())
 {
  return 0;
 }
    // 取得一个该GUID相关的设备信息集句柄
    hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE,     // class GUID 
        NULL,                    // 无关键字 
        NULL,                    // 不指定父窗口句柄 
        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备
        
    // 失败...
    if (hDevInfoSet == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }
  
    // 申请设备接口数据空间
     
    nCount = 0;
    bResult = TRUE;
 for (i=0; i< 34; i++)
 {
  bDeviceOpen[i] = FALSE;
  memset(m_DeviceDesc[i], 0, 256);
 }
  
 SP_DEVICE_INTERFACE_DATA ifdata;
    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
    while (bResult)
    {
  
        ifdata.cbSize = sizeof(ifdata);
        // 枚举符合该GUID的设备接口
        bResult = ::SetupDiEnumDeviceInterfaces(
            hDevInfoSet,     // 设备信息集句柄
            NULL,            // 不需额外的设备描述
            (LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE,          // GUID
            (ULONG)nCount,   // 设备信息集里的设备序号
            &ifdata);        // 设备接口信息
  
        if (bResult)
        {
   ULONG                                predictedLength = 0;
   ULONG                                requiredLength = 0;
   // 取得该设备接口的细节(设备路径)
            bResult = SetupDiGetInterfaceDeviceDetail(
                hDevInfoSet,    // 设备信息集句柄
                &ifdata,        // 设备接口信息
                NULL,        // 设备接口细节(设备路径)
                0,    // 输出缓冲区大小
                &requiredLength,           // 不需计算输出缓冲区大小(直接用设定值)
                NULL);          // 不需额外的设备描述
            // 取得该设备接口的细节(设备路径)
   predictedLength=requiredLength;
  // if(pDetail)
  // {
  //  pDetail =NULL;
  // }
            pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);
            pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
   bResult = SetupDiGetInterfaceDeviceDetail(
                hDevInfoSet,    // 设备信息集句柄
                &ifdata,        // 设备接口信息
                pDetail,        // 设备接口细节(设备路径)
                predictedLength,    // 输出缓冲区大小
                &requiredLength,           // 不需计算输出缓冲区大小(直接用设定值)
                NULL);          // 不需额外的设备描述
  
            if (bResult)
            {
                // 复制设备路径到输出缓冲区
                //::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
    if (strcmp(m_sysversion, "winnt")==0)
    {
     char ch[18];
     for(i=0;i<17;i++){
      ch[i]=*(pDetail->DevicePath+8+i);
     }
     ch[17]='/0';
     if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错
     {
     
      memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;    
      memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;   
      READ_OS.hEvent = CreateEvent( NULL,    // no security
               TRUE,    // explicit reset req
              FALSE,   // initial event reset
               NULL ) ; // no name
      if (READ_OS.hEvent == NULL)   
      {
       break;
      }
       
      WRITE_OS.hEvent = CreateEvent( NULL,    // no security
               TRUE,    // explicit reset req
              FALSE,   // initial event reset
               NULL ) ; // no name
         if (NULL == WRITE_OS.hEvent)
      {
         CloseHandle( READ_OS.hEvent );
         break;
      }
      
      hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
       GENERIC_READ|GENERIC_WRITE,
                FILE_SHARE_READ|FILE_SHARE_WRITE,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL/*|
       FILE_FLAG_OVERLAPPED*/,
       NULL);
      if (hUsb != NULL)
      {
       // 比较定位找到的USB在哪个USB PORT上
       char id[30];
       memset(id, 0, 30);
       i=0;
       do
       {
        id[i]=*(pDetail->DevicePath+26+i);
        i++;
       }
       while(id[i-1]!='#');
       id[i-1] = '/0';
       for (j=0; j<34; j++)
       {
        if(strcmp(id, m_USBList[j])==0)
        {
         sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
         m_USBPositionMap[nCount] = j+1;
         break;
        }
       }
       CloseHandle(hUsb);
       nCount++;
      // break;
      }
     }// 比较驱动版本
    }// 比较操作系统版本
    else
    {
     memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;    
     memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;   
     READ_OS.hEvent = CreateEvent( NULL,    // no security
              TRUE,    // explicit reset req
             FALSE,   // initial event reset
              NULL ) ; // no name
     if (READ_OS.hEvent == NULL)   
     {
      break;
     }
       
     WRITE_OS.hEvent = CreateEvent( NULL,    // no security
              TRUE,    // explicit reset req
             FALSE,   // initial event reset
              NULL ) ; // no name
        if (NULL == WRITE_OS.hEvent)
     {
        CloseHandle( READ_OS.hEvent );
        break;
     }
      
     hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
         GENERIC_READ|GENERIC_WRITE,
                  FILE_SHARE_READ|FILE_SHARE_WRITE,
         NULL,
         OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL/*|
         FILE_FLAG_OVERLAPPED*/,
         NULL);
     if (hUsb != NULL)
     {
      if(strcmp(pDetail->DevicePath, m_USBList[j])==0)
      {
       sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
       m_USBPositionMap[nCount] = j+1;
       break;
      }
      CloseHandle(hUsb);
      nCount++;
     // break;
     }
    }
   }
  }
 }
    // 释放设备接口数据空间
    ::GlobalFree(pDetail);
  
    // 关闭设备信息集句柄
 ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
 iDeviceCount = nCount;
 return nCount;
}

// 写
BOOL Writestr(char *buf,int buflen, int index)
{
 BOOL  fWriteStat;
 DWORD       dwErrorFlags;
 DWORD    dwError;
 COMSTAT     ComStat;
 char        szError[ 10 ] ;
    DWORD       ret;
 int   len, i, j, packet;
 div_t  div_result;
 BYTE  sendpacket[65];
 BYTE  xorcode=0x00;
 if (m_gphdCom[index] == NULL)  // no usb device(jk100c)
 {
  return -1;
 }
 div_result = div(buflen, 58);
 if (div_result.rem == 0)
 {
  packet = div_result.quot;
 }
 else
 {
  packet = div_result.quot+1;
 }
 for (i=0; i<packet; i++)
 {
  memset(sendpacket, 0, 65);
  if(i==packet-1)
  {
   // end packet
   if (div_result.rem == 0)
   {
    len = 58;
   }
   else
   {
    len = div_result.rem;
   }
  }
  else
  {
   len = 58;
  }
  sendpacket[0] = 0x13;
  sendpacket[1] = 3+len;
  sendpacket[2] = 0x01;
  sendpacket[3] = packet*16+i+1;
  memcpy(sendpacket+4, buf+(i*58), len);
  for(j=0;j<len+3;j++)
  {
   xorcode^=sendpacket[j+1];
  }
  sendpacket[len+4] = (char)xorcode;
  sendpacket[len+5] = 0x23;
    PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
//  Sleep(10);
  fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL);
  if (!fWriteStat) 
  {
   if(GetLastError() == ERROR_IO_PENDING)
   {
    dwError = GetLastError();
    // an error occurred, try to recover
    wsprintf( szError, "/n/r <CE-%u>", dwError ) ;
    OutputDebugString(szError);
    ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
    if (dwErrorFlags >0)
    {
     wsprintf( szError, "/n/r <CE-%u>", dwErrorFlags ) ;
     OutputDebugString(szError);
     }
   }
   else
   {        
    // some other error occurred
    ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
    if (dwErrorFlags > 0)
    {
     wsprintf( szError, "/n/r <CE-%u>", dwErrorFlags ) ;
     OutputDebugString(szError);
    }
    return FALSE;
   }
  }
  if (i != packet-1)
  {
   // should be receive ack
   if (ReceivePacketAnswer(index) != 0)
   {
    return FALSE;
   }
  }
 }
 
 return TRUE;
}
// 读
int Readstr(char *buf,int nMaxLength, int index)
{
    BOOL       fReadStat ;
 COMSTAT    ComStat;
 DWORD      dwErrorFlags;
 DWORD      dwLength;
 DWORD      dwError;
 char       szError[ 10 ];
    
 if (fCOMMOpened==0)
 {
  return FALSE; //串口未打开
 }
 // only try to read number of bytes in queue 
 ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;
 //dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
    
 dwLength=nMaxLength;
 if (dwLength > 0)
 {
  if (olap==TRUE) 
  {
     fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ;
     if (!fReadStat)
      {
      if (GetLastError() == ERROR_IO_PENDING)
      {
       OutputDebugString("/n/rIO Pending");
       while(!GetOverlappedResult(m_gphdCom[index], &READ_OS, 
                &dwLength, TRUE ))
       {
        dwError = GetLastError();
           if(dwError == ERROR_IO_INCOMPLETE) continue;
           else
        {
            // an error occurred, try to recover
         ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;
            break;
        }
       }
      }
      else // end-----if (GetLastError() == ERROR_IO_PENDING)
      {
       // some other error occurred
       dwLength = 0 ;
       ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
       if (dwErrorFlags >0)
       {
        wsprintf( szError, "/n/r <CE-%u>", dwErrorFlags ) ;
        OutputDebugString(szError);
       }
      }
     } // end-----if (!fReadStat) 
  } // end-----if (olap==TRUE) 
  else
  {
   fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ;
   if (!fReadStat)
   {
    dwError = GetLastError();
    ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;
      
    if (dwErrorFlags >0)
    {
     wsprintf( szError, "/n/r <CE-%u>", dwErrorFlags ) ;
     OutputDebugString(szError);
    }
   }
   PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
     }
 }
    return  dwLength;
}
FAQ:
1,如果是指硬件(固件),那么先要看使用什么USB接口芯片,根据芯片资料,编写固件完成发送/接收数据的功能.如果芯片是采用带USB   HID接口的单片机,操作更简单,只要读写特殊的地址,就可以了,具体操作还要看硬件的资料
2,如果指PC编程,在WINDOWS下找到此设备的符号链接名,用CreateFile打开,然后用ReadFile/WriteFile读写就可以了,要用到SetupApi,如果感兴趣可以继续讨论