请教串口发送数据发送不完全的问题

askForAll 2005-06-02 09:34:02
小弟在使用串口进行通讯的时候,发现有时候会出现发送数据不全的情况(比如我的命令有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,各位大侠有没有什么好的解决方案
...全文
874 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
askForAll 2005-06-28
  • 打赏
  • 举报
回复
好象是我自己线程的问题,我收到的回复放在一个字串队列里,那边设备的回复没有问题,是我这边的同步出了问题。明明已经setevent通知主线程了,但是这边waitforsingleobject就是会超时。关键是还不太好重复,偶尔机器忙才会出现这个问题。
qrlvls 2005-06-10
  • 打赏
  • 举报
回复
不需要 FlushFileBuffers
通过多线程处理发送缓冲区就好,再大的数据处理也不会影响到发送数据丢失
askForAll 2005-06-07
  • 打赏
  • 举报
回复
怎么没人顶啊,人肉up!
程序猿KL 2005-06-06
  • 打赏
  • 举报
回复
推荐 龚建伟 《Visual C++/Turbo C串口通信编程实践》 自己在看!感觉不错!!
askForAll 2005-06-06
  • 打赏
  • 举报
回复
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)了.
qinxiaogang 2005-06-06
  • 打赏
  • 举报
回复
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, ................. )
xnlcx 2005-06-05
  • 打赏
  • 举报
回复

我用CodeGuru上的CSerialPort怎么没有出过问题呢
龚建伟 《Visual C++/Turbo C串口通信编程实践》上有的
AthlonxpX86 2005-06-05
  • 打赏
  • 举报
回复
这是很正常的事情,PC的串口是有缓冲的,WriteFile只是把数据写到驱动程序,此时可能并没有真正的发送你可以在串口设备属性选项卡的高级属性中找到,关闭后就好了,不过可能会出现效率低下的问题。
另外串口程序可以有一个函数可以用来解决这个问题,函数我既不太清楚了,好像是FlashBuffer之类
superbert 2005-06-05
  • 打赏
  • 举报
回复
我好象有类似的问题,不知道怎么解决?

帮你顶了
askForAll 2005-06-04
  • 打赏
  • 举报
回复
没人回吗?人肉up
Kernel_Don 2005-06-04
  • 打赏
  • 举报
回复
常用的方法是在接收端把每次接到的数据存入缓冲区,把几次接收到的数据拼成完整的命令。
askForAll 2005-06-03
  • 打赏
  • 举报
回复
那已经发送的那四个字节怎么办啊。
而且今天我发现在特定情况下还存在通讯延迟的问题。
当两边机器都比较忙的时候,主机接收回复超时(我设定为3秒)就会重发一遍命令,接下来再发另一条命令,然后三条回复就过来了,产生了回复紊乱。
碧螺春的马甲 2005-06-03
  • 打赏
  • 举报
回复
只有重发这个思路。

重要的是通信协议中的差错处理!
askForAll 2005-06-03
  • 打赏
  • 举报
回复
发送的数据没有包头包尾,不过有CRC校验.因为我发送的是命令,在设备里应该有存储所有命令的表,所以不用包头包尾.但是收到的回复数据是有包头包尾和校验的.
zhangnanonnet 2005-06-03
  • 打赏
  • 举报
回复
发送的数据包采用包头,包尾和CRC校验吧
askForAll 2005-06-03
  • 打赏
  • 举报
回复
接收端是用的NDI公司的仪器,我通过串口和他的API命令和仪器进行通讯,协议是他们定的。我这边发送完如果没有回复就再发一遍,如果回复错误就报错。很简单的。
碧螺春的马甲 2005-06-03
  • 打赏
  • 举报
回复
这个就是接受端收到乱码怎么拌的问题。我觉得凉拌比较好。

任何通信都会存在错误、延迟、重复、缺失,特别是自己开发的东西并没有去遵循任何协议,任何保证通信质量的协议。

那么我想问的是,你的通信如何处理这些错误情况的。
再次简化代码,取消串口,直接显示结果,仍然有问题!!

疑问代码如下:
struct _USB_DATA_STRUCT
{
/*
unsigned char command_data[40];//release结果正确
int command_index;
int command_size;
int numofnod;
*/
int command_index;
int command_size;
int numofnod;
unsigned char command_data[40];//release结果错误

void SetData(unsigned char* pdata,int size)
{
if(size>40)
{
AfxMessageBox("数据太大,超范围!");
return;
}
memcpy(command_data,pdata,size);
}
};

void CTestprjDlg::OnButton1()
{
// TODO: Add your control notification handler code here
unsigned char ctem[32];//错误:32,103,104; 正确:105,110

USB_DATA_STRUCT CommandData;//需要填写要发送的数据

ctem[0]=0xee;
ctem[1]=0x01;
memset(ctem+2,0x00,30);

CommandData.SetData(ctem,32);

ShowTest(CommandData.command_data,32);
}

void CTestprjDlg::ShowTest(unsigned char* p,int nlen)
{
CString str = _T("");
for(int i=0;i <32;i++)
{
CString tmp_str;
tmp_str.Format("0x%02X ", p[i]);
str += tmp_str;
}
m_textctrl.SetWindowText(str);
}

//VC6

Debug版本没有问题,输出如:
EE 01 00 00 00...后面全0
Release版本(按Maximize speed优化)有问题,输出如:
EE 01 00 00 00 00 00 00 00 00 00 00 EE 01 00 00 00 00 00 00 00 00 00 00 EE 01 00 00 00 00 00 00

Release版本下,按以下修改没有问题
1.调整ctem的大小。小于等于104有问题,大于等于105没有问题
2.将ctem改为char* ctem;
ctem=new char[32];
没有问题

3.优化方式由Maximize speed修改为Minimize code也没问题

请教可能是什么原因?

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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