CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  硬件/系统

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

楼主askForAll(偶碰机了)2005-06-02 21:34:02 在 VC/MFC / 硬件/系统 提问

小弟在使用串口进行通讯的时候,发现有时候会出现发送数据不全的情况(比如我的命令有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

相关问题

  • 如何在向串口发送的数据量巨大的情况下,能完全接受数据
  • 串口按二进制数据发送
  • 串口发送数据问题:
  • 从串口发送数据包问题
  • 串口发送数据问题
  • 串口发送非字符数据
  • 串口数据
  • 如何用VC编写向串口发送数据的程序?
  • delphi中利用串口发送数据的问题
  • 用PB如何向串口发送16进制的数据

关键词

  • visual c++
  • 数据
  • 协议
  • 通讯
  • 通信
  • 串口
  • purge
  • 回复
  • 发送
  • hcomm

得分解答快速导航

  • 帖主:askForAll

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo