对获取EF3返回锁存点功能,基本实现
This commit is contained in:
@@ -189,6 +189,15 @@ DWORD CPSerial::Open()
|
||||
if (SetupComm(m_PortHandle, 2048, 2048))
|
||||
{
|
||||
// Setup the event masks for the monitoring task
|
||||
// 设置你关心的事件, 当此事件发生时, 将得到事件通知, 通过SetCommMask函数设置, SetCommMask函数两个参数, 第一个为串口句柄, 第二个为事件, 可通过位或的方式指定多个事件,如下:
|
||||
// BOOL WINAPI SetCommMask(
|
||||
// __in HANDLE hFile,
|
||||
// __in DWORD dwEvtMask);
|
||||
|
||||
//示例代码:
|
||||
// SetCommMask(m_hCom, EV_RXCHAR);
|
||||
// EV_RXCHAR事件指当输入缓冲区内有数据时, 通过WaitCommEvent函数可获得通知, 其他事件同理, 其他事件还有EV_BREAK / EV_CTS / EV_RING等,
|
||||
|
||||
if (SetCommMask(m_PortHandle, EV_RXCHAR | EV_TXEMPTY | EV_BREAK |
|
||||
EV_CTS | EV_DSR | EV_ERR | EV_RLSD))
|
||||
{
|
||||
@@ -444,7 +453,7 @@ DWORD CPSerial::WritePort(const char* Buffer, DWORD Bytes)
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//单纯读取单包串口数据,拼包功能在上层实现
|
||||
int CPSerial::ReadBlock(BYTE* abIn, int MaxLength)
|
||||
{
|
||||
@@ -454,14 +463,26 @@ int CPSerial::ReadBlock(BYTE* abIn, int MaxLength)
|
||||
ClearCommError(m_PortHandle, &dwErrorFlags, &ComStat);
|
||||
if (dwErrorFlags > 0)
|
||||
{
|
||||
//PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR
|
||||
//分别表示:
|
||||
//立即中断写操作并清空输出缓冲区 | 清空输出缓冲区 | 立即中断读操作并清空输入缓冲区 | 清空输入缓冲区
|
||||
PurgeComm(m_PortHandle, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||
return 0;
|
||||
}
|
||||
dwLength = (static_cast<DWORD>(MaxLength) < ComStat.cbInQue ? MaxLength : ComStat.cbInQue);
|
||||
//memset(abIn, 0, MaxLength);
|
||||
//如果有字符即读入, 这种策略下无法解决读入的字符不是完整的一帧的问题 Bug
|
||||
//如果有字符即读入, 这种策略下无法解决读入的字符不是完整的一帧的问题
|
||||
if (dwLength)
|
||||
{
|
||||
//BOOL ReadFile(
|
||||
// HANDLE hFile, //文件的句柄
|
||||
// LPVOID lpBuffer, //用于保存读入数据的一个缓冲区
|
||||
// DWORD nNumberOfBytesToRead, //要读入的字节数
|
||||
// LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针
|
||||
// LPOVERLAPPED lpOverlapped
|
||||
// //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。
|
||||
// //该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
|
||||
//);
|
||||
JudgeRead = ReadFile(m_PortHandle, abIn, dwLength, &dwLength, &m_ReceiveOLap); //读出字符至abIn处
|
||||
if (!JudgeRead)
|
||||
{
|
||||
@@ -469,10 +490,17 @@ int CPSerial::ReadBlock(BYTE* abIn, int MaxLength)
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
// WaitForSingleObject(m_osRead.hEvent,INFINITE);
|
||||
GetOverlappedResult(m_PortHandle, &m_ReceiveOLap, &dwLength, TRUE);
|
||||
GetOverlappedResult(m_PortHandle, &m_ReceiveOLap, &dwLength, TRUE); //等待一次异步读取完成
|
||||
m_ReceiveOLap.Offset = 0;
|
||||
// m_osRead.Offset=(m_osRead.Offset+dwLength)%MAXBLOCK;
|
||||
|
||||
//等待一次异步操作超时的情况下,GetOverlappedResult返回FALSE,同时GetLastError返回ERROR_IO_INCOMPLETE
|
||||
/* if (WaitForSingleObject(m_osRead.hEvent, 1000) == WAIT_TIMEOUT)
|
||||
{
|
||||
dwLength = 0;
|
||||
} */
|
||||
}
|
||||
//异常情况
|
||||
else
|
||||
{
|
||||
dwLength = 0;
|
||||
@@ -482,9 +510,69 @@ int CPSerial::ReadBlock(BYTE* abIn, int MaxLength)
|
||||
return dwLength;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ReceiveTask() : Internal function, this runs as a thread and provides the
|
||||
// OnRecieve and OnTransmit events
|
||||
int CPSerial::Receive(void* buf, int maxlen, bool sync)
|
||||
{
|
||||
//HANDLE hCom = *(HANDLE*)m_PortHandle;
|
||||
|
||||
if (sync)
|
||||
{
|
||||
|
||||
//同步方式
|
||||
DWORD wCount = maxlen; //成功读取的数据字节数
|
||||
BOOL bReadStat = ReadFile(m_PortHandle, //串口句柄
|
||||
buf, //数据首地址
|
||||
wCount, //要读取的数据最大字节数
|
||||
&wCount, //DWORD*,用来接收返回成功读取的数据字节数
|
||||
NULL); //NULL为同步发送,OVERLAPPED*为异步发送
|
||||
if (!bReadStat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return wCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//异步方式
|
||||
DWORD wCount = maxlen; //成功读取的数据字节数
|
||||
DWORD dwErrorFlags; //错误标志
|
||||
COMSTAT comStat; //通讯状态
|
||||
OVERLAPPED m_osRead; //异步输入输出结构体
|
||||
|
||||
//创建一个用于OVERLAPPED的事件处理,不会真正用到,但系统要求这么做
|
||||
memset(&m_osRead, 0, sizeof(m_osRead));
|
||||
//m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, L"ReadEvent");
|
||||
|
||||
ClearCommError(m_PortHandle, &dwErrorFlags, &comStat); //清除通讯错误,获得设备当前状态
|
||||
if (!comStat.cbInQue)return 0; //如果输入缓冲区字节数为0,则返回false
|
||||
|
||||
BOOL bReadStat = ReadFile(m_PortHandle, //串口句柄
|
||||
buf, //数据首地址
|
||||
wCount, //要读取的数据最大字节数
|
||||
&wCount, //DWORD*,用来接收返回成功读取的数据字节数
|
||||
&m_osRead); //NULL为同步发送,OVERLAPPED*为异步发送
|
||||
if (!bReadStat)
|
||||
{
|
||||
if (GetLastError() == ERROR_IO_PENDING) //如果串口正在读取中
|
||||
{
|
||||
//GetOverlappedResult函数的最后一个参数设为TRUE
|
||||
//函数会一直等待,直到读操作完成或由于错误而返回
|
||||
GetOverlappedResult(m_PortHandle, &m_osRead, &wCount, TRUE);
|
||||
|
||||
/* memcpy(m_RecvData, buf, wCount);
|
||||
m_iRecvBytes = wCount;
|
||||
m_iRecvState = true;*/
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearCommError(m_PortHandle, &dwErrorFlags, &comStat); //清除通讯错误
|
||||
CloseHandle(m_osRead.hEvent); //关闭并释放hEvent的内存
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return wCount;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// C prototype : void HexToStr(char *pszDest, byte *pbSrc, int nLen)
|
||||
@@ -510,19 +598,22 @@ void CPSerial::hex2str(char* pszDest, byte* pbSrc, int nLen)
|
||||
pszDest[nLen * 2] = '\0';
|
||||
}
|
||||
|
||||
#if 1
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ReceiveTask() : Internal function, this runs as a thread and provides the
|
||||
// OnRecieve and OnTransmit events
|
||||
void CPSerial::ReceiveTask(void)
|
||||
{
|
||||
//DWORD BytesWritten;
|
||||
DWORD Events;
|
||||
unsigned long State;
|
||||
|
||||
int temp_Packlen = 0; //临时存放包长度
|
||||
do
|
||||
{
|
||||
Sleep(2);
|
||||
Sleep(3);
|
||||
BYTE abIn[MAXBLOCK];
|
||||
int len;
|
||||
len = ReadBlock(abIn, MAXBLOCK); //单包读取
|
||||
//len = ReadBlock(abIn, MAXBLOCK); //读取一包串口数据
|
||||
len = Receive(abIn, MAXBLOCK, 0);//方式2
|
||||
if ((len > 0) && (len < MAX_RECIEVE_BUFFER_SIZE))
|
||||
{
|
||||
//memset(m_RecvData, 0, m_iRecvBytes);
|
||||
@@ -530,37 +621,54 @@ void CPSerial::ReceiveTask(void)
|
||||
{
|
||||
auto pszDest = new char[len * 2 + 1];
|
||||
hex2str(pszDest, abIn, len);
|
||||
printf("len=%d, m_iExpectBytes=%d, %s\n", len, m_iExpectBytes, pszDest);
|
||||
printf("kaishi len=%d, m_iExpectBytes=%d, %s\n", len, m_iExpectBytes, pszDest); //打印单包数据,每次可以从这里得到单包数据
|
||||
}
|
||||
if (m_iExpectBytes != 0) //当有期望值时,进行拼包
|
||||
{
|
||||
//循环拼包
|
||||
if (m_iRecvBytes < m_iExpectBytes)
|
||||
{
|
||||
while (m_iRecvBytes < m_iExpectBytes)
|
||||
{
|
||||
memcpy(m_RecvData + m_iRecvBytes, abIn, len);
|
||||
m_iRecvBytes += len;
|
||||
|
||||
auto pszDest = new char[m_iRecvBytes * 2 + 1];
|
||||
hex2str(pszDest, m_RecvData, m_iRecvBytes);
|
||||
printf("11111=%d %s\n", m_iRecvBytes, pszDest);
|
||||
}
|
||||
}
|
||||
else // 大于等于期望返回数量,成功
|
||||
{
|
||||
memcpy(m_RecvData, abIn, len);
|
||||
m_iRecvBytes = len;
|
||||
m_iRecvState = TRUE;
|
||||
}
|
||||
}
|
||||
else //无期望返回数量时,随机返回单包数据
|
||||
// 第一层判断,当前接收正好为期望返回
|
||||
if (len == m_iExpectBytes)
|
||||
{
|
||||
memcpy(m_RecvData, abIn, len);
|
||||
m_iRecvBytes = len;
|
||||
m_iRecvState = TRUE;
|
||||
m_iRecvState = true;
|
||||
|
||||
printf("=====");
|
||||
temp_Packlen = 0;
|
||||
}
|
||||
|
||||
// 第二层判断,当前接收为期望返回的一部分
|
||||
else if (len < m_iExpectBytes)
|
||||
{
|
||||
memcpy(m_RecvData + temp_Packlen, abIn, len);
|
||||
temp_Packlen += len;
|
||||
|
||||
//打印拼包后的数据
|
||||
auto pszDest = new char[m_iRecvBytes * 2 + 1];
|
||||
hex2str(pszDest, m_RecvData, m_iRecvBytes);
|
||||
printf("pinbao = %d %s\n", m_iRecvBytes, pszDest);
|
||||
|
||||
// 第三层判断,当前接收为期望返回的最后一部分
|
||||
if (temp_Packlen == m_iExpectBytes)
|
||||
{
|
||||
m_iRecvBytes = temp_Packlen;
|
||||
m_iRecvState = true;
|
||||
|
||||
printf("pinbao========");
|
||||
}
|
||||
}
|
||||
|
||||
// 第四层判断,当前接收为期望返回的超出部分,以实际接收为准
|
||||
else if (len > m_iExpectBytes)
|
||||
{
|
||||
memcpy(m_RecvData, abIn, len);
|
||||
m_iRecvBytes = len;
|
||||
m_iRecvState = true;
|
||||
|
||||
printf(">>>>>>>>>>>>========");
|
||||
temp_Packlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Events=0;
|
||||
//
|
||||
// // Wait for a comm event
|
||||
@@ -614,7 +722,7 @@ void CPSerial::ReceiveTask(void)
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void CPSerial::ReceiveTask(void)
|
||||
{
|
||||
@@ -685,9 +793,10 @@ void CPSerial::OnReceive()
|
||||
char s[MAX_RECIEVE_BUFFER_SIZE] = {0};
|
||||
s[1] = '\0';
|
||||
CurrentPointer = 0;
|
||||
int num = 0;
|
||||
if (m_HandShake == CS_HANDSHAKE_FOR_TRESASTR_E)
|
||||
{
|
||||
int num = ReadPort(s, MAX_RECIEVE_BUFFER_SIZE);
|
||||
num = ReadPort(s, MAX_RECIEVE_BUFFER_SIZE);
|
||||
if ((num > 0) && (num < MAX_RECIEVE_BUFFER_SIZE))
|
||||
{
|
||||
if (m_IsWrtingData)
|
||||
@@ -709,7 +818,7 @@ void CPSerial::OnReceive()
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = ReadPort(s, m_iRecvCount);
|
||||
num = ReadPort(s, m_iRecvCount);
|
||||
printf("----Data received:: %d----\r\n", num);
|
||||
if ((num > 0) && (num < MAX_RECIEVE_BUFFER_SIZE))
|
||||
{
|
||||
@@ -723,7 +832,7 @@ void CPSerial::OnReceive()
|
||||
}
|
||||
}
|
||||
}
|
||||
//LineReceive(s, num);
|
||||
LineReceive(s, num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user