📄 robindlg.cpp
字号:
{
//UpdateData(TRUE);
//Variables to store Vid, Pid and SerialNumbers
WORD Vid, Pid;
CP2101_SERIAL_STRING serialNum;
//Loop through and display data for each connected device
// for (int i = 0; i < m_dwNumDevices; i++)
// {
// Query the Vid, Pid and Serial number of each device.
// We will use this information to look up the device
// in the registry to find the port number. There are also
// examples of displaying other items in the registry as well.
// Open device
CP2101_STATUS status = CP2101_Open(0, &m_hUSBDevice);
if (status == CP2101_SUCCESS)
{
// Get Vid
status = CP2101_GetDeviceVid(m_hUSBDevice, &Vid);
if (status == CP2101_SUCCESS)
{
// Get Pid
status = CP2101_GetDevicePid(m_hUSBDevice, &Pid);
if (status == CP2101_SUCCESS)
{
BYTE bLength = 0;
CString tmpDevStr;
// Get Serial Number
status = CP2101_GetDeviceSerialNumber(m_hUSBDevice, serialNum, &bLength);
// Null terminate to make it a string
serialNum[bLength] = '\0';
//Display our current information about the device we found
tmpDevStr.Format("Found Device: VID=%04X, PID=%04X", Vid, Pid);
}
}
}
// This is a function call to obtain the port number
// by passing the Vid, Pid, and SN of the device in
// question. An integer value with the port is passed back
int Port;
DWORD winVersion = GetVersion() & VERSION_MASK;
if (winVersion == VERSION_WINXP2000)
Port = GetPortNumXP2000(Vid, Pid, serialNum);
else if (winVersion == VERSION_WIN98)
Port = GetPortNum98(Vid, Pid, serialNum);
// Text formatting for display of the com port
DCB dcbPort1InitState, dcbPort1;
CString COMPort1;
COMPort1.Format("\\\\.\\COM%u", Port);
CP2101_Close(m_hUSBDevice);
m_hUSBDevice = INVALID_HANDLE_VALUE;
if(Port!=-1)
{
m_comstatus.Format("COM%u ON", Port);
UpdateData(FALSE);
}
// Create the Handles
hDev1 = CreateFile(COMPort1, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
if(hDev1 == INVALID_HANDLE_VALUE)
{
MessageBox("Error: Invalid Handle Value for Device 1.");
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
//m_output = "";
}
else
{
if(!PurgeComm(hDev1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) // device 1 fails
{
//m_output = "Error: Failed to purge COM port for device 1.";
MessageBox("Error: Failed to purge COM port for Device 1.");
}
else
{
if(!GetCommState(hDev1, &dcbPort1InitState)) // port 1 fails to get its current state
{
//m_output = "Error: Failed to get current state of port 1.";
MessageBox("Error: Failed to get current state of port 1.");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
else
{
dcbPort1 = dcbPort1InitState;
dcbPort1.BaudRate = 19200;
dcbPort1.Parity = NOPARITY;
dcbPort1.ByteSize = 8;
dcbPort1.StopBits = ONESTOPBIT;
if(!SetCommState(hDev1, &dcbPort1)) // fails to set port 1 state
{
//m_output = "Error: Failed to set the state of port 1.";
MessageBox("Error: Failed to set the state of port 1.");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
else
{
DelayMS(60);
if(!Transfer())
MessageBox("Error: Failed to transfer data.");
}
}
}
}
// Closing the handles
// if (hDev1 != INVALID_HANDLE_VALUE) CloseHandle(hDev1);
// hDev1 = INVALID_HANDLE_VALUE;
// }
//UpdateData(FALSE);
}
bool CMyDlg::Transfer()
{
BYTE dataStart[] = {0x66};
nUser = 1;
bool success = false;
OVERLAPPED o = {0};
o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
UINT timeout = 3000;
DWORD* written = (DWORD*)malloc(sizeof(DWORD));
DWORD toBeWritten = 1;
if(!WriteFile(hDev1, (LPCVOID)dataStart, toBeWritten, written, &o))//send START flag
{
if(GetLastError() == ERROR_IO_PENDING)
{
if(WaitForSingleObject(o.hEvent, INFINITE) == WAIT_OBJECT_0)
if(GetOverlappedResult(hDev1, &o, written, FALSE))
success = true;
}
// surprise removal case
else if (GetLastError() == ERROR_OPERATION_ABORTED)
{
MessageBox("Surprise Removal on Device Write!");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
}
else
success = true;
if(*written != toBeWritten)
success = false;
if(success) // read the sum of users that will be uploaded
{
phase=1;
TimeOutRd=500;
SetTimer(1,10,NULL);
}
return success;
}
void CMyDlg::FillDeviceList()
{
EnumDevices();
GetDeviceData();
}
void CMyDlg::EnumDevices()
{
//Obtain the number of connected devices
CP2101_STATUS status = CP2101_GetNumDevices(&m_dwNumDevices);
if(m_dwNumDevices<1) MessageBox("Error: No Supported Device.");
if(m_dwNumDevices>1) MessageBox("Error: Please Get Rid of Other USB Devices.");
}
// GetPortNum functions takes the Vid, Pid, and SerialNumber and
// returns an integer containing the COM port that the device is
// connected to (different functions for Win98/WinXP2000)
int CMyDlg::GetPortNumXP2000(WORD vid, WORD pid, char* ser)
{
//Variables used for Registry access
HKEY tmpKey, tmpSubKey, tmpPortKey;
CString portKeyString;
DWORD valtype;
char* portString;
DWORD length = 100;
portString = new char[101];
//Set portnum to -1, so if there is an error we will
//know by returning a negative port value
int portNum = -1;
// Open keys to get to the key where the port number is located. This key is:
// HKLM\System\CurrentControlSet\Enum\USB\Vid_xxxx&Pid_yyyy&Mi_00\zzzz_00\DeviceParameters\PortName
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\", 0, KEY_READ, &tmpKey))
{
if (ERROR_SUCCESS == RegOpenKey(tmpKey, "Enum\\USB\\", &tmpSubKey))
{
//Loop through and replace spaces for WinXP2000
int i = 0;
while (ser[i] != '\0')
{
if (ser[i] == 0x20)
ser[i] = '_';
i++;
}
//The portkey string should look like this
//"Vid_XXXX&Pid_XXXX&MI_00\\XXXX_00" where the XXXX's are Vid, Pid and serial string
portKeyString.Format("Vid_%04x&Pid_%04x&Mi_00\\%s_00\\Device Parameters\\", vid, pid, ser);
//If the portkey string is in the registry, then go ahead and open the portname
if (ERROR_SUCCESS == RegOpenKey(tmpSubKey, portKeyString, &tmpPortKey))
{
if (ERROR_SUCCESS == RegQueryValueEx(tmpPortKey, "PortName", NULL, &valtype, (unsigned char *)portString, &length))
{
// When we obtain this key, it will be in string format of
// "COMXX" where XX is the port. Simply make the first three
// elements of the string 0, and call the atoi function to obtain
// the number of the port.
portString[0] = '0';
portString[1] = '0';
portString[2] = '0';
portNum = atoi(portString);
}
//Make sure to close all open keys for cleanup
RegCloseKey(tmpPortKey);
}
RegCloseKey(tmpSubKey);
}
RegCloseKey(tmpKey);
}
RegCloseKey(HKEY_LOCAL_MACHINE);
// Return the number of the port the device is connected too
return portNum;
}
int CMyDlg::GetPortNum98(WORD vid, WORD pid, char* ser)
{
//Variables used for Registry access
HKEY tmpKey;
CString portKeyString, serKeyString;
int serialIndex;
DWORD valtype;
char* portString;
DWORD length = 100;
portString = new char[101];
//Set portnum to -1, so if there is an error we will
//know by returning a negative port value
int portNum = -1;
//We will search through the keys by index, starting at 0
//Use this index in the key "Enum\SLABCR\guid\XXXX"
serialIndex = 0;
serKeyString.Format("Enum\\SLABCR\\guid\\%.4d", serialIndex);
//Loop through and convert the serial string to all upper case and replace spaces for Win98
int i = 0;
while (ser[i] != '\0')
{
if (ser[i] == 0x20)
ser[i] = '_';
else if ((ser[i] >= 0x61) && (ser[i] <= 0x7A))
ser[i] -= 32;
i++;
}
//The portkey string should look like this when we query the CLowerDeviceID
//"USB\VID_XXXX&PID_XXXX&MI_00\\XXXX_00" where the XXXX's are Vid, Pid and serial string
portKeyString.Format("USB\\VID_%04X&PID_%04X&MI_00\\%s_00", vid, pid, ser);
// Open keys to get to the key where the port number is located. This key is:
// HKLM\Enum\SLABCR\guid\XXXX\Portname is the key and we will loop through each key in the registry
while (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, serKeyString, &tmpKey))
{
// Determine the status of the call
DWORD status = RegQueryValueEx(tmpKey, "CRLowerDeviceID", NULL, &valtype, (unsigned char *)portString, &length);
// If we need to make the call again, then decrement the serial index so we can access
// it the next time through the loop
if (ERROR_MORE_DATA == status)
serialIndex--;
// Otherwise, the call is a success, and we can compare the portString from the key
// to the port string that we want, if they match then retrieve the port
else if (ERROR_SUCCESS == status)
{
if (portString == portKeyString)
{
if (ERROR_SUCCESS == RegQueryValueEx(tmpKey, "Portname", NULL, &valtype, (unsigned char *)portString, &length))
{
// When we obtain this key, it will be in string format of
// "COMXX" where XX is the port. Simply make the first three
// elements of the string 0, and call the atoi function to obtain
// the number of the port.
portString[0] = '0';
portString[1] = '0';
portString[2] = '0';
portNum = atoi(portString);
}
}
}
// Increment the serial index
serialIndex++;
serKeyString.Format("Enum\\SLABCR\\guid\\%.4d", serialIndex);
//Make sure to close all open keys for cleanup
RegCloseKey(tmpKey);
}
RegCloseKey(HKEY_LOCAL_MACHINE);
// Return the number of the port the device is connected too
return portNum;
}
void CMyDlg::DelayMS(UINT delay)
{
DWORD start, end;
start = end = GetTickCount();
// Wait for 'delay' milliseconds.
while ((end - start) < delay)
{
end = GetTickCount();
}
}
void CMyDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
KillTimer(1);
CTime Read_date;
BYTE dataAck[]={0xAA};
BYTE dataError[]={0x55};
BYTE dataSum[3];
BYTE dataRead[72];
BYTE checksum = 0xFF;
bool success = false;
OVERLAPPED o = {0};
o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
UINT timeout = 3000;
DWORD* written = (DWORD*)malloc(sizeof(DWORD));
DWORD* read = (DWORD*)malloc(sizeof(DWORD));
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD toBeWritten = 1, toBeRead = 72;
ClearCommError( hDev1 , &dwErrorFlags, &ComStat ) ;
if ((ComStat.cbInQue == 3)&&(phase==1))
{
success = false;
if(!ReadFile(hDev1, dataSum, 3, read, &o))
{
if(GetLastError() == ERROR_IO_PENDING)
{
if(WaitForSingleObject(o.hEvent, timeout) == WAIT_OBJECT_0)
{
if(GetOverlappedResult(hDev1, &o, read, FALSE))
{
nUser=(short int)(dataSum[0] & 0x0F)*100+(short int)(dataSum[1] & 0x0F)*10+(short int)(dataSum[2] & 0x0F);
success = true;
}
}
else // timeout case
MessageBox("Timeout on Device Read");
}
// surprise removal case
else if (GetLastError() == ERROR_ACCESS_DENIED)
{
MessageBox("Surprise Removal on Device Read!");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
}
else
{
nUser=(short int)(dataSum[0] & 0x0F)*100+(short int)(dataSum[1] & 0x0F)*10+(short int)(dataSum[2] & 0x0F);
success = true;
}
if((success)&&(nUser>0))
{
if(!PurgeComm(hDev1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) // device 1 fails
{
//m_output = "Error: Failed to purge COM port for device 1.";
MessageBox("Error: Failed to purge COM port for Device 1.");
}
else
{
if(!WriteFile(hDev1, (LPCVOID)dataAck, toBeWritten, written, &o))//send START flag
{
if(GetLastError() == ERROR_IO_PENDING)
{
if(WaitForSingleObject(o.hEvent, INFINITE) == WAIT_OBJECT_0)
if(GetOverlappedResult(hDev1, &o, written, FALSE))
success = true;
}
// surprise removal case
else if (GetLastError() == ERROR_OPERATION_ABORTED)
{
MessageBox("Surprise Removal on Device Write!");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
}
else
success = true;
if(*written != toBeWritten)
success = false;
if(success) // read the sum of users that will be uploaded
{
TimeOutRd=500;
phase=2;
SetTimer(1,10,NULL);
}
}
}
}
else
{
if(phase==1) SetTimer(1,10,NULL);
}
//Start Receive User Data
if ((ComStat.cbInQue == toBeRead)&&(phase==2))
{
success = false;
if(!ReadFile(hDev1, dataRead, toBeRead, read, &o))
{
if(GetLastError() == ERROR_IO_PENDING)
{
if(WaitForSingleObject(o.hEvent, timeout) == WAIT_OBJECT_0)
{
if(GetOverlappedResult(hDev1, &o, read, FALSE))
{
success = true;
}
}
else // timeout case
MessageBox("Timeout on Device Read");
}
// surprise removal case
else if (GetLastError() == ERROR_ACCESS_DENIED)
{
MessageBox("Surprise Removal on Device Read!");
CloseHandle(hDev1);
hDev1 = INVALID_HANDLE_VALUE;
CommFlag = false;
m_buttonul.SetWindowText("&Start");
m_comstatus.Replace("ON","OFF");
UpdateData(FALSE);
}
}
else
{
success = true;
}
if(success)
{
for(int i=1;i<68;i++) checksum ^= dataRead[i];
if(1)//((checksum==(((dataRead[69]&0x0F)<<4)|(dataRead[70]&0x0F)))&&(dataRead[0]==0x99)&&(dataRead[0]==0x99)&&(dataRead[71]==0xEE))
{
nUser--;
success = true;
}
else
success = false;
}
if(success)
{
//****************just for debug******************//
UINT nByteN,iL;
CString strT1,strT2;
nByteN=72;
strT2="";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -