⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbadcserverdlg.cpp

📁 USB设备在人体工学接口模式驱动的设备读写通讯程序.在TMS32F103上测试通过
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			SP_DEVINFO_DATA did = {sizeof(SP_DEVINFO_DATA)};
			
			if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&ifData,detail,needed,NULL,&did)){
				if(	strstr(detail->DevicePath,"vid_4d41") != NULL && 
					strstr(detail->DevicePath,"pid_464c") != NULL ){
					DevicePath = detail->DevicePath;
					DevicePath.MakeUpper();				
					break;
				}
			}
			delete[] (PBYTE)detail;
		}
		SetupDiDestroyDeviceInfoList(hDevInfo);
	}

	hHidDevice = CreateFile((LPCTSTR)DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
							NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
	if(hHidDevice != INVALID_HANDLE_VALUE){
		PHIDD_ATTRIBUTES Attributes = (PHIDD_ATTRIBUTES)malloc(sizeof(HIDD_ATTRIBUTES));
		if(HidD_GetAttributes(hHidDevice,Attributes)){			
		
			PHIDP_PREPARSED_DATA	PreParsedData;
			HidD_GetPreparsedData(hHidDevice,&PreParsedData);
			HidP_GetCaps(PreParsedData,&pDevCapabilities);
			m_vUsbName.Format("PID%04X VID%04X REV%04X IN%02X OUT%02X",
						Attributes->ProductID,Attributes->VendorID,Attributes->VersionNumber,
						pDevCapabilities.InputReportByteLength,pDevCapabilities.OutputReportByteLength );
			memset(Product,0,24);
			HidD_GetSerialNumberString(hHidDevice,(PVOID)Product,26);
			CString tmpStr;
			DeviceSN.Empty();
			for(int i=0;i<12;i++){
				tmpStr.Format("%02X",(unsigned char)Product[i*2]);
				DeviceSN+=tmpStr;
				if(i%2==1)DeviceSN+=" ";
			}
			m_vUsbsn=DeviceSN;			
		
			if(ThreadOpened == FALSE){			
				if(_beginthread(RecvThreadFunction, 0, hHidDevice) >= 0){	//打开接收线程
					CreateThreadWR();
					GetDlgItem(IDC_BTN_MANUAL)->EnableWindow(1);
					GetDlgItem(IDC_BTN_SFILE)->EnableWindow(1);
					ThreadOpened = TRUE;
				}
			}
		}
	}else{		
		ThreadOpened = FALSE;		
		//bThreadGoing = FALSE;
		GetDlgItem(IDC_BTN_MANUAL)->EnableWindow(0);
		GetDlgItem(IDC_BTN_SFILE)->EnableWindow(0);
		m_vUsbName	="设备未连接!";
		m_vUsbsn	="";
	}
	
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
DWORD WINAPI CUSBADCserverDlg::WriteReport(void *)
{
	static	DWORD		NumberOfBytesWriten;			//must be global variable or static variable
	static	OVERLAPPED	HidOverlapped;
	
	while(TRUE){
		if(WRITE_ROPRT){
			if(hHidDevice != INVALID_HANDLE_VALUE){
				WriteFile(hHidDevice,OutputReport,pDevCapabilities.OutputReportByteLength,
					&NumberOfBytesWriten,(LPOVERLAPPED)&HidOverlapped);
				WRITE_ROPRT = FALSE;
			}
		}
		_sleep(10);
	}
	return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//建立线程
DWORD CUSBADCserverDlg::CreateThreadWR()
{
	if(hWriteThread!= NULL)	CloseHandle(hWriteThread);

	hWriteThread = CreateThread(NULL,0,WriteReport,NULL,0,&WriteThreadId);
	if(hWriteThread == NULL)AfxMessageBox("建立写线程错误,错误号为: %d !",GetLastError());

	return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//接收线程,程序启动即开始运行监测USB数据接收
void __cdecl RecvThreadFunction(HANDLE hHidDevice)
{
    CString msg;
	UINT  i;
	DWORD recvdBytes;

    HANDLE hIOWaiter = CreateEvent(NULL, TRUE, FALSE, NULL);

    if(hIOWaiter == NULL)  goto exit2;

    OVERLAPPED OverLapped;
    OverLapped.Offset = 0;
    OverLapped.OffsetHigh = 0;
    OverLapped.hEvent = hIOWaiter;


    for(i=0;bThreadGoing ==TRUE;i++){
        if(i>=IN_REPORTS_NUM)i=0;
        ResetEvent(hIOWaiter);

        if(!ReadFile(hHidDevice, &InputReport[i], pDevCapabilities.InputReportByteLength, &recvdBytes, &OverLapped)) {		//ReadFile->         
            DWORD err = GetLastError();
            if(err != ERROR_IO_PENDING && err != ERROR_DEVICE_NOT_CONNECTED && bThreadGoing){
                msg.Format("读操作错误: %d", err);
               AfxMessageBox(msg); goto exit1;		//未知异常退出
            }

            while(WaitForSingleObject(hIOWaiter, 1) == WAIT_TIMEOUT){
                if(!bThreadGoing){						//查询读中止标志
					if(hHidDevice != INVALID_HANDLE_VALUE){
                        CancelIo(hHidDevice);		
                    }
                    goto exit1;					
                }
            }
            if(!GetOverlappedResult(hHidDevice, &OverLapped, &recvdBytes, false)){ 
				err = GetLastError();
				if(err != ERROR_DEVICE_NOT_CONNECTED && bThreadGoing){
					msg.Format("GetOverlappedResult例程错误: %d", err); 
                    AfxMessageBox(msg);				//例和出错
					if(hHidDevice != INVALID_HANDLE_VALUE){
                        CancelIo(hHidDevice);		
                    }
					goto exit1;
				}
            }
        }
        AfxGetMainWnd()->SendMessage(IDM_RECV_DATA,(UINT )i, (LPARAM)(&InputReport[i]));		
    }

exit1:
    CloseHandle(hIOWaiter);

exit2:
    _endthread();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
LONG CUSBADCserverDlg::OnReceivedData(UINT wParam, LONG lParam)
{
	CString tmpStr;
	if(bAutoClear)m_vRecv = "";
	for(int i=0;i< pDevCapabilities.InputReportByteLength ;i++){
		FileBuffer[FilePos]=InputReport[wParam][i];
		if(++FilePos > FILE_MAX_SIZE)	FilePos = FILE_MAX_SIZE;
		tmpStr.Format("%02X ",InputReport[wParam][i]);
		m_vRecv += tmpStr;
	}
	dReportsRecv ++;
    return (LRESULT) 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnManual() 
{
	int i,m;
	u8		hexbuf[1024];
	u8		chrbuf[2048];

	if(ThreadOpened==FALSE)return;

	UpdateData(TRUE);

	m = m_vSend.GetLength();
	if(m>2048)m=2048;
	if(m==0)return;
	for(i=0;i<m;i++)chrbuf[i]=m_vSend.GetAt(i);
	for(;i<2048;i++) chrbuf[i]=0;
	
	m/=2;
	StringToHex(chrbuf,hexbuf,m);

	if(	m > pDevCapabilities.OutputReportByteLength)
		m = pDevCapabilities.OutputReportByteLength;

	for(i=0;i<m;i++)OutputReport[i]= hexbuf[i];
	
	m_vSend="";
	m_vRecv="";

	m_vCnts.Format("%d",++dReportsSent);
	m_cCnts.SetWindowText(m_vCnts);

	WRITE_ROPRT = TRUE;	
	
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnSfile() 
{
	DWORD i;

	CFileDialog FileDialog(TRUE,NULL,"",OFN_HIDEREADONLY,"USB数据文件(*.BIN)|*.BIN|所有类型 (*.*)|*.*||");
	if(FileDialog.DoModal()!=IDOK)return ;

	CString PathFile	= FileDialog.GetPathName();
	CString ExtFile		= FileDialog.GetFileExt();

	CFile	pDataFile;
	if(!pDataFile.Open(PathFile,CFile::typeBinary|CFile::modeRead,NULL)){
		AfxMessageBox("建立文件错误\r\n"+PathFile);
		return ;
	}
	
	DWORD	m = pDataFile.GetLength();

	if(m > pDevCapabilities.OutputReportByteLength) 
		m = pDevCapabilities.OutputReportByteLength;

	for(i=0;i< pDevCapabilities.OutputReportByteLength ; i++)
		OutputReport[i]=0;
	pDataFile.Read(OutputReport,m);

	pDataFile.Close();	


	if(m==0)return;
	
	CString tmpStr;
	m_vSend = "";
	for(i=0;i<m;i++){
		tmpStr.Format("%02X ",OutputReport[i]);
		m_vSend += tmpStr;
	}
	m_cSend.SetWindowText(m_vSend);

	m_vRecv="";
	m_cRecv.SetWindowText(m_vRecv);
	
	m_vCnts.Format("%d",++dReportsSent);
	m_cCnts.SetWindowText(m_vCnts);

	WRITE_ROPRT = TRUE;	

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnRclear() 
{
	m_vRecv = "";
	m_cRecv.SetWindowText(m_vRecv);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckRfile() 
{
	DWORD	tm,md;

		CString	FileName = m_vUsbName + " " + m_vUsbsn + ".BIN";
		CFileDialog FileDialog(TRUE,NULL,FileName,OFN_HIDEREADONLY,"USB数据文件(*.BIN)|*.BIN|所有类型 (*.*)|*.*||");
		if(FileDialog.DoModal()!=IDOK)return ;

		CString PathFile	= FileDialog.GetPathName();
		CString ExtFile		= FileDialog.GetFileExt();

		
		if(!pDataFile.Open(PathFile,CFile::typeBinary|CFile::modeWrite|CFile::modeCreate,NULL)){
			AfxMessageBox("建立文件错误\r\n"+PathFile);
			return ;
		}
		tm = FilePos / FILE_PAGE_SIZE;
		md = FilePos % FILE_PAGE_SIZE;
		FilePos  = 0;
		for(DWORD i=0;i<tm;i++)pDataFile.Write(FileBuffer,i * FILE_PAGE_SIZE);
		pDataFile.Write(FileBuffer,i * FILE_PAGE_SIZE + md);
		pDataFile.Close();	
	
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckAutos() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	UINT	n = m_iPeriod;
	if(n<3)n=3;
	if(m_cAutoS.GetCheck())	SetTimer(TIMER_AUTOS,n,NULL);
	else						KillTimer(TIMER_AUTOS);
	UpdateData(FALSE);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckAutoc() 
{
	// TODO: Add your control notification handler code here
	if(m_cAutoC.GetCheck())	bAutoClear=TRUE;
	else					bAutoClear=FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnClear() 
{
	// TODO: Add your control notification handler code here
	dReportsSent = dReportsRecv =0;
	m_vCnts.Format("%d",dReportsSent);
	m_cCnts.SetWindowText(m_vCnts);
	m_vCntr.Format("%d",dReportsRecv);
	m_cCntr.SetWindowText(m_vCntr);
	FilePos = 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnOk() 
{
	// TODO: Add your control notification handler code here
	if(hHidDevice	!=INVALID_HANDLE_VALUE)CloseHandle(hHidDevice);

	if(hWriteThread	!=INVALID_HANDLE_VALUE)CloseHandle(hWriteThread);
	CDialog::OnOK();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//功能:	将字符串转换成为十六进制数,
//输入:	str:	输入字符串,其数据有效为'0'~09','a'~'f','A'~'F',间隔符可有可无,有时须是数据之外的
//		hex:		输出数据指针
//		len:		输出数据缓冲最大长度,若字符串数据不够,返回实际个数,超出时返回len
//返回:	输出数据字节数	
u16	StringToHex(u8 *str,u8 *hex,u16 len)
{
	u16	i,j;
	u8	chnew,chold;
	u8	begin,stop;
	
	begin=0;stop=0;chold=0;
	for(i=0,j=0;j/2<len;i++){
		chnew=*(str+i);
		if		(chnew==0)					break;
		else if	(chnew>='0'&&chnew<='9')	{chnew=chnew-'0';}
		else if	(chnew>='a'&&chnew<='f')	{chnew=chnew-'a'+10;}
		else if	(chnew>='A'&&chnew<='F')	{chnew=chnew-'A'+10;}
		else								{chnew=16;}
		if(chnew<16){					
			if(j%2==0)	hex[j/2] =chnew*16;
			else		hex[j/2]+=chnew;
			j++;
		}else if(chold<16){				
			if(j%2==1)	{				
				hex[(j-1)/2]/=16;
				j++;
			}
		}								
		chold=chnew;
	}
	for(i=j/2;i<len;i++)hex[i]=0;			//结束符后全清零
	return j/2;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -