”我正在编写程序,该程序在com端口串行通信上同步写入数据,并且在writefile之后放置睡眠时读取操作也是同步的,但是它可以正常工作,但是如果删除睡眠,那么我会得到一些错误数据,其中0x20空间不是所有数据都是错误但有些字节”
我已经添加了我已经使用过的写入文件和读取文件,并且还创建了文件,请告知我哪里错了
int CCommLink::WriteComm (HANDLE hComm, void* pBuf, int iLen, DWORD dwTimeToWait, UINT nBaud)
{
OVERLAPPED ol;
memset (&ol, 0, sizeof(OVERLAPPED));
ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
COMSTAT ComStat;
DWORD dwErrorFlags, dwBytesWrite;
// ---------------------------------------------------------------------
// clear the buffer
// ---------------------------------------------------------------------
ClearCommError (hComm, &dwErrorFlags, &ComStat);
dwBytesWrite = (DWORD)ComStat.cbOutQue;
if (dwBytesWrite)
{
DWORD dwTickCount = GetTickCount();
do
{
ClearCommError (hComm, &dwErrorFlags, &ComStat);
dwBytesWrite = (DWORD)ComStat.cbOutQue;
} while ( dwBytesWrite && GetTickCount() - dwTickCount <
dwTimeToWait);
}
// ----------------------------------------------------------------
// write the data to the serial port
// ---------------------------------------------------------------------
if (!WriteFile (hComm, pBuf, iLen, &dwBytesWrite, NULL))
{
if (GetLastError() == ERROR_IO_PENDING)
{
// GetOverlappedResult(hComm, &ol, &dwBytesWrite, TRUE);
WaitForSingleObject (ol.hEvent, iLen * 40000 / nBaud);
dwBytesWrite = iLen;
}
else
{
// CString cs = GetLastErrorStr();
return 0;
}
}
return dwBytesWrite;
}
******************* read file function************************
int CCommLink::ReadComm (HANDLE hComm, void* pBuf, DWORD dwTimeToWait, UINT nBaud, DWORD dwBytesToRead)
{
// dwTimeToWait=100;
OVERLAPPED ol;
memset (&ol, 0, sizeof(OVERLAPPED));
ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
COMSTAT ComStat;
DWORD dwErrorFlags, dwBytesRead;
ClearCommError (hComm, &dwErrorFlags, &ComStat);
dwBytesRead = (DWORD)ComStat.cbInQue;
if (!dwBytesRead)
{
if (!dwTimeToWait)
return 0;
DWORD dwTickCount = GetTickCount();
do
{
ClearCommError (hComm, &dwErrorFlags, &ComStat);
dwBytesRead = (DWORD)ComStat.cbInQue;
} while (!dwBytesRead && GetTickCount() - dwTickCount < dwTimeToWait);
}
if (!dwBytesRead)
return -1;
if (dwBytesRead > dwBytesToRead)
dwBytesRead = dwBytesToRead;
(void)memset((void *)pBuf, ' ', (size_t)256);
if (!ReadFile (hComm, pBuf, 1, &dwBytesRead, NULL))
{
LogResult(_T("********************************************ERROR WHILE READING ***********************************************"));
if (GetLastError() == ERROR_IO_PENDING)
{
DWORD w = (32*10000) / nBaud;
if (!w)
w = 16;
WaitForSingleObject (ol.hEvent, w);
dwBytesRead = 1;
}
else
dwBytesRead = 0;
}
CString str= LogStr((unsigned char*)pBuf ,1);
LogResult(str);
// pBuf=(void*)UxRx;
if (!dwBytesRead)
{
// CString cs = GetLastErrorStr();
return -2;
}
return (int)dwBytesRead;
}
HANDLE CCommLink::SetComm (int iPort, UINT nBaud, int Parity, int StopBits)
{
// ---------------------------------------------------------------------
// open a port handle
// ---------------------------------------------------------------------
CString cPort;
if (iPort < 10)
cPort.Format(_T("COM%d"), iPort);
else
cPort.Format(_T("\\\\.\\COM%d"), iPort);
HANDLE hPort = CreateFile(
cPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,// FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (INVALID_HANDLE_VALUE == hPort)
return INVALID_HANDLE_VALUE;
// ---------------------------------------------------------------------
// set communication buffer size
// ---------------------------------------------------------------------
if (!SetupComm(hPort, eSize_LinkBuffer*2, eSize_LinkBuffer*2)) // h,in,out
{
CloseHandle (hPort);
return INVALID_HANDLE_VALUE;
}
// ---------------------------------------------------------------------
// set timeout contants
// ---------------------------------------------------------------------
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 80000/nBaud ? 80000/nBaud : 1;
CommTimeOuts.WriteTotalTimeoutConstant = CommTimeOuts.WriteTotalTimeoutMultiplier * 8;
if( !SetCommTimeouts(hPort, &CommTimeOuts) )
{
CloseHandle (hPort);
return INVALID_HANDLE_VALUE;
}
// ---------------------------------------------------------------------
// set port configurations
// ---------------------------------------------------------------------
DCB dcb; // Initialize the DCBlength member.
dcb.DCBlength = sizeof (DCB); // Get the default port setting information.
GetCommState (hPort, &dcb);
// Change the DCB structure settings.
dcb.BaudRate = nBaud; // Current baud
dcb.fBinary = TRUE; // Binary mode: no EOF check
dcb.fParity = TRUE; // Parity checking: Disable
dcb.fOutxCtsFlow = FALSE; // No CTS output flow control
dcb.fOutxDsrFlow = FALSE; // No DSR output flow control
dcb.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
dcb.fDsrSensitivity = FALSE; // DSR sensitivity
dcb.fTXContinueOnXoff = TRUE; // XOFF continues Tx
dcb.fOutX = FALSE; // No XON/XOFF out flow control
dcb.fInX = FALSE; // No XON/XOFF in flow control
dcb.fErrorChar = TRUE; // Disable error replacement
dcb.fNull = FALSE; // Disable null stripping
dcb.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
dcb.fAbortOnError = FALSE; // Do not abort reads/writes on: error
dcb.ByteSize = 8; // Number of bits/BYTE, 4-8
dcb.Parity = Parity; // 0-4=no,odd,even,mark,space
dcb.StopBits = StopBits; // 0,1,2 = 1, 1.5, 2
dcb.ErrorChar = ' '; // reaplacement of the TCHAR with parity error
if (!SetCommState (hPort, &dcb))
{
CloseHandle (hPort);
return INVALID_HANDLE_VALUE;
}
return hPort;
}
答案 0 :(得分:0)
您的ReadFile()
可能返回TRUE(成功),而pBuf
中没有数据。要解决此问题,您可以将ReadIntervalTimeout
设置为例如10(毫秒)而不是MAXDWORD
,因为:
MAXDWORD的值,与两个 ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier成员, 指定读取操作将立即返回 已收到的字节,即使没有字节 收到。
(下面与您的问题没有直接关系,但有一些代码提示)。
由于设置了同步操作而不是异步操作,因此存在一些冗余代码行:
OVERLAPPED ol;
memset (&ol, 0, sizeof(OVERLAPPED));
ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
WaitForSingleObject();
为了使重叠的操作生效。您需要为CrateFile()
设置FILE_FLAG_OVERLAPPED
标志,并为WriteFile()
和ReadFile()
配置OVERLAPPED结构;
//...
HANDLE hPort = CreateFile(
L"COM8",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
//...
WriteFile(hComm, pBuf, iLen, NULL, &ol);
//...
ReadFile(hComm, pBuf, 1, NULL, &ol);