请教串口发送数据发送不完全的问题
小弟在使用串口进行通讯的时候,发现有时候会出现发送数据不全的情况(比如我的命令有11个字符,它只发送4个),特别是主机在进行视频播放等大数据量处理而比较忙的时候.这让我很痛苦,因为直接会导致接收数据的紊乱.
我的串口通讯是异步方式的,下面是往串口写数据的代码:
void CSerialPort::WriteChar(CSerialPort* port)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
ResetEvent(port->m_hWriteEvent);
// Gain ownership of the critical section
EnterCriticalSection(&port->m_csCommunicationSync);
if (bWrite)
{
// Initailize variables
port->m_ov.Offset = 0;
port->m_ov.OffsetHigh = 0;
// Clear buffer
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
bResult = WriteFile(port->m_hComm, // Handle to COMM Port
port->m_szWriteBuffer,
// Pointer to message buffer in calling finction
(DWORD)port->m_nStringLength, // Length of message to send//strlen((char*)port->m_szWriteBuffer)
&BytesSent,// Where to store the number of bytes sent
&port->m_ov); // Overlapped structure
// deal with any error codes
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
{
// continue to GetOverlappedResults()
BytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
// all other error codes
port->ProcessErrorMessage("WriteFile()");
}
}
}
else
{
LeaveCriticalSection(&port->m_csCommunicationSync);
}
} // end if(bWrite)
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult( port->m_hComm, // Handle to COMM port
&port->m_ov, // Overlapped structure
&BytesSent, // Stores number of bytes sent
TRUE); // Wait flag
LeaveCriticalSection(&port->m_csCommunicationSync);
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
}
} // end if (!bWrite)
// flush the COM Port...this sends out any info still sitting in the buffer //add 11.05
EnterCriticalSection(&port->m_csCommunicationSync);
FlushFileBuffers( port->m_hComm );
LeaveCriticalSection(&port->m_csCommunicationSync);
// Verify that the data size send equals what we tried to send
if ( BytesSent != (DWORD)port->m_nStringLength )
{
TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
}
}
每次发生接收紊乱的时候trace窗都会显示WriteFile() error,各位大侠有没有什么好的解决方案
问题点数:0、回复次数:17Top
1 楼jslisong(碧螺春)回复于 2005-06-03 09:17:48 得分 0
只有重发这个思路。
重要的是通信协议中的差错处理!Top
2 楼askForAll(偶碰机了)回复于 2005-06-03 11:20:40 得分 0
那已经发送的那四个字节怎么办啊。
而且今天我发现在特定情况下还存在通讯延迟的问题。
当两边机器都比较忙的时候,主机接收回复超时(我设定为3秒)就会重发一遍命令,接下来再发另一条命令,然后三条回复就过来了,产生了回复紊乱。Top
3 楼jslisong(碧螺春)回复于 2005-06-03 14:31:36 得分 0
这个就是接受端收到乱码怎么拌的问题。我觉得凉拌比较好。
任何通信都会存在错误、延迟、重复、缺失,特别是自己开发的东西并没有去遵循任何协议,任何保证通信质量的协议。
那么我想问的是,你的通信如何处理这些错误情况的。Top
4 楼askForAll(偶碰机了)回复于 2005-06-03 14:37:12 得分 0
接收端是用的NDI公司的仪器,我通过串口和他的API命令和仪器进行通讯,协议是他们定的。我这边发送完如果没有回复就再发一遍,如果回复错误就报错。很简单的。Top
5 楼zhangnanonnet(鱼欢)回复于 2005-06-03 16:14:19 得分 0
发送的数据包采用包头,包尾和CRC校验吧Top
6 楼askForAll(偶碰机了)回复于 2005-06-03 17:27:35 得分 0
发送的数据没有包头包尾,不过有CRC校验.因为我发送的是命令,在设备里应该有存储所有命令的表,所以不用包头包尾.但是收到的回复数据是有包头包尾和校验的.Top
7 楼askForAll(偶碰机了)回复于 2005-06-04 12:37:44 得分 0
没人回吗?人肉upTop
8 楼Kernel_Don()回复于 2005-06-04 23:12:09 得分 0
常用的方法是在接收端把每次接到的数据存入缓冲区,把几次接收到的数据拼成完整的命令。Top
9 楼AthlonxpX86(一坨屎)回复于 2005-06-05 10:18:06 得分 0
这是很正常的事情,PC的串口是有缓冲的,WriteFile只是把数据写到驱动程序,此时可能并没有真正的发送你可以在串口设备属性选项卡的高级属性中找到,关闭后就好了,不过可能会出现效率低下的问题。
另外串口程序可以有一个函数可以用来解决这个问题,函数我既不太清楚了,好像是FlashBuffer之类Top
10 楼xnlcx(J2EE.Net)回复于 2005-06-05 12:10:41 得分 0
我用CodeGuru上的CSerialPort怎么没有出过问题呢
龚建伟 《Visual C++/Turbo C串口通信编程实践》上有的Top
11 楼superbert(烂苹果)回复于 2005-06-05 14:45:03 得分 0
我好象有类似的问题,不知道怎么解决?
帮你顶了Top
12 楼qinxiaogang(qinxg)回复于 2005-06-06 09:08:58 得分 0
1. // Clear buffer
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // 去掉
2. 添加: WaitForSingleObject( port->m_hWriteEvent.hEvent, INFINITE );
GetOverlappedResult( m_hComm, ................. )
Top
13 楼askForAll(偶碰机了)回复于 2005-06-06 10:25:16 得分 0
To Kernel_Don() :我有数据缓冲和拼接的,我可以完整地接收到回复.但是现在的问题是它有时候在我设定的回复时间内没有任何内容返回.
To AthlonxpX86(桃源村) :是不是FlushFileBuffers( port->m_hComm );我有调用的,不知道它会不会把缓冲区的都发出去.打个问号?
To qinxiaogang(qinxg):1,为什么要去掉PurgeComm,能具体说说吗?
2,GetOverlappedResult( port->m_hComm,&port->m_ov,&BytesSent,TRUE); 最后一个参数就相当于在waitForSingleObject(...,INFINITE)了. Top
14 楼Jasonsystem(梦之子)回复于 2005-06-06 10:38:06 得分 0
推荐 龚建伟 《Visual C++/Turbo C串口通信编程实践》 自己在看!感觉不错!!Top
15 楼askForAll(偶碰机了)回复于 2005-06-07 20:03:27 得分 0
怎么没人顶啊,人肉up!Top
16 楼qrlvls( 空 气 )回复于 2005-06-10 11:27:24 得分 0
不需要 FlushFileBuffers
通过多线程处理发送缓冲区就好,再大的数据处理也不会影响到发送数据丢失Top
17 楼askForAll(偶碰机了)回复于 2005-06-28 12:40:44 得分 0
好象是我自己线程的问题,我收到的回复放在一个字串队列里,那边设备的回复没有问题,是我这边的同步出了问题。明明已经setevent通知主线程了,但是这边waitforsingleobject就是会超时。关键是还不太好重复,偶尔机器忙才会出现这个问题。Top




