[串口]为什么我的串口Read事件在空字符情况下也会有信号?

jobine 2005-04-28 04:27:52
我参考的是网上较多的那个CSerialPort类,但是每次读过输入缓冲区后,紧跟着又有EV_RXCHAR事件发生,而且发现是空的输入(constat.cbInQue的值是0),请问这是为什么?有什么办法不让这个紧跟的事件发生?
...全文
216 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jobine 2005-04-29
  • 打赏
  • 举报
回复
自己顶一下
jobine 2005-04-29
  • 打赏
  • 举报
回复
to Practise_Think: 应该是接受了一个空数据,我对错误信息都有判断。刚刚lclvcstudy说的超时问题我还不太清楚,能否再解释一下?
Practise_Think 2005-04-29
  • 打赏
  • 举报
回复
每次从串口的缓冲区取完数据后,在缓冲区里的这些数据都会自动清除掉的,如果仍有数据的话,就得看看这些数据是否是有效数据或是这只是一个报错返回!!
lclvcstudy 2005-04-29
  • 打赏
  • 举报
回复
^_^,我来答一下,你应该是没有延时,就是当串口没有字符时,要隔一段时间再报告串口中没有字符了,这是我写的串口类,在公司一直使用,比较好用,其中用了一个事件来去控制串口字符的读写

memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);

if(os.hEvent==NULL)
{
AfxMessageBox("无法创建事件对象!");
return -1;
}

SerialPort->m_FlagEndThread = 0;

for(;;)
{
comstat.cbInQue = 0;
ClearCommError(SerialPort->m_handleComm,&dwError,&comstat);

if(comstat.cbInQue)
{
WaitForSingleObject(SerialPort->m_msgEvent,INFINITE);
ResetEvent(SerialPort->m_msgEvent);
SerialPort->ReadChar(SerialPort->buffer);
::SendMessage((SerialPort->m_pOwner)->m_hWnd,
WM_COMM_RXCHAR,
(WPARAM)(comstat.cbInQue),
(LPARAM)(SerialPort->m_portNR));

continue;
}

if(SerialPort->m_FlagEndThread)
{
CloseHandle(os.hEvent);
return 0;
}
EventComm = 0;
RWait = WaitCommEvent(SerialPort->m_handleComm,
&EventComm,
&os); //wait the events


if(!RWait)
{


switch(dwError = GetLastError())
{
case ERROR_IO_PENDING: //normal result
{
WaitForSingleObject(os.hEvent,120000);

if(!GetOverlappedResult(SerialPort->m_handleComm,
&os,
&SizeBytesRead,
FALSE))
{

CloseHandle(os.hEvent);
AfxMessageBox("串口缓存里没有字符");
return FALSE;
}
break;
}
case 87:
{
// Under Windows NT, this value is returned for some reason.
// I have not investigated why, but it is also a valid reply
// Also do nothing and continue.
break;
}
default:
{
CloseHandle(os.hEvent);
AfxMessageBox("串口发生了影响读的错误");
return FALSE;
}
}//end switch
}//end if

}//end for loop
jobine 2005-04-29
  • 打赏
  • 举报
回复
是的,我是用串口调试工具发送的。发送端没有发送空数据,另外以后发送端是硬件实现的,也不能去清除发送端的数据缓冲。
lizhenzhou 2005-04-29
  • 打赏
  • 举报
回复
哦,就是说有空字符来触发EV_RXCHAR,可以保证发送端没有发空数据?发送端,发完总可以清理一下write buffer吧
jobine 2005-04-29
  • 打赏
  • 举报
回复
to 零点派,因为我的数据过来没有固定规律,有可能这次取完,数据马上就过来了,所以不能清理buffer。
98440622 2005-04-29
  • 打赏
  • 举报
回复
串行通信标准库,纯API开发,无需注册

98440622@163.com
lizhenzhou 2005-04-29
  • 打赏
  • 举报
回复
每次读完buffer,清理一下读buffer?可以吗?
jobine 2005-04-28
  • 打赏
  • 举报
回复
我利用事件驱动控制串口的读写,在创建串口时CreateEvent了三个事件读、写、推出线程。在线程回调函数中GetForMultipleObjects等待IO操作发生。当有数据发送到本机的串口时,会激活读事件,然后我会调用ReadBuff去读输入缓冲,并返回所读出的字节数。但是当我读出了缓冲区中所有的数据后,不知为什么系统又触发了一次读事件,这次事件中输入缓冲中明明是没有数据的(利用ClearCommError可以得到comstat,其中cbInQue记录着缓冲中的字节长度)。线程回调函数如下:
UINT COPComm::CommWatchThread(LPVOID lpParam)
{
DWORD dwEvent = 0, dwCommMask = 0, /*dwBytes,*/ dwError;
COMSTAT comstat;
COPComm *pParam = (COPComm*)lpParam;
BOOL bCommState;

if (NULL == pParam)
{
return 1;
}

PurgeComm(pParam->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

while (pParam->m_bCommOpen)
{
bCommState = WaitCommEvent(pParam->m_hComm, &dwEvent, &pParam->m_ov);
if (!bCommState)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
break;
case 87:
break;
default:
pParam->ProcessError("WaitCommEvent()");
break;
}
}
else
{
ClearCommError(pParam->m_hComm, &dwError, &comstat);
if (comstat.cbInQue == 0)
{
continue;
}
}

//main watch function which will normally block thread until one event occurs
dwEvent = WaitForMultipleObjects(3, pParam->m_hEventArray, FALSE, INFINITE);
switch (dwEvent)
{
case 0: //shutdown event, kill the thread
AfxEndThread(100);
break;

case 1: //read
static DWORD k;
GetCommMask(pParam->m_hComm, &dwCommMask);
if (dwCommMask & EV_RXCHAR == EV_RXCHAR)
{
k = pParam->ReadBuff(pParam->m_szBuff, BUFFER_LENGTH);
if (k > 0)
::SendMessage(pParam->m_pOwner->m_hWnd, WM_COMM_RXCHAR, (WPARAM)k, 0);
}
break;

case 2: //write
break;
}
}//while

return 0;
}
xuzheng318 2005-04-28
  • 打赏
  • 举报
回复
楼主能不能说得再详细点
不太明白
zztoll 2005-04-28
  • 打赏
  • 举报
回复
是不是你重复读取数据了?

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧