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

串口通信中使用SendMessage发现问题,请高手指点。

楼主fu256(大圣)2004-11-03 00:28:04 在 VC/MFC / 基础类 提问

我建一个串口类  
  class   CCom  
  {  
      .  
      .  
      CCom()     {   m_bComOpen=FALSE;   };  
   
      BOOL                       m_bComOpen  
      CWinThread     *     m_Thread;  
   
      init(...);       //初始化  
      static   UINT   ComThread(LPCIOD   lp);     //监视线程  
      RecChar();       //在线程中的有接收事件时调用此函数读数据,并SendMessage   发到窗口。  
      .  
      .  
  }  
    要求运行中改变串口。  
    我在init()中  
                    ...  
  if   (m_bComOpen)  
  {  
  m_bComOpen=FALSE;  
  SetEvent(m_hShutdownEvent);  
  WaitForSingleObject(m_Thread->m_hThread,INFINITE);  
  delete   m_Thread;  
  }  
                    ...打开串口并配置  
  if   (!(m_Thread   =   AfxBeginThread(CommThread,   this)))  
  {  
  m_bComOpen=FALSE;  
  return   FALSE;  
  }else  
  {  
  m_Thread->m_bAutoDelete=FALSE;  
                                      m_bComOpen=TRUE;  
                        return   TRUE;  
  }  
   
      在ComThread(LPCIOD   lp)中  
                    ...  
  m_hEventArray[0]   =   m_hShutdownEvent; //   高优先级  
  m_hEventArray[1]   =   m_ov.hEvent;  
    Event   =   WaitForMultipleObjects(2,   port->m_hEventArray,   FALSE,INFINITE);  
  switch   (Event)  
  {  
          case   0:         //退出线程     init()中   SetEvent(m_hShutdownEvent);  
  return   0;  
  break;  
          case   1: //   read   event  
  GetCommMask(port->m_hComm,   &CommEvent);  
  if   (CommEvent   &   EV_RXCHAR)         //   Receive   character   event   from   port.  
  RecChar(port,   comstat);  
  break;  
  }      
   
   
      在RecChar()中  
                    ...  
                     
  while   (1)    
  {    
      EnterCriticalSection(&port->m_csCommunicationSync);  
      bResult   =   ClearCommError(port->m_hComm,   &dwError,   &comstat);  
      LeaveCriticalSection(&port->m_csCommunicationSync);  
      if   (comstat.cbInQue   ==   0)  
  break;  
   
      EnterCriticalSection(&port->m_csCommunicationSync);  
   
    bResult   =   ReadFile(port->m_hComm,&RXBuff,   1,&BytesRead,&port->m_ov);  
    bResult   =   GetOverlappedResult(port->m_hComm, &port->m_ov,&BytesRead,TRUE);    
    if   (!bResult)      
    {  
            port->Error("GetOverlappedResults()   in   ReadFile()");  
    }  
    LeaveCriticalSection(&port->m_csCommunicationSync);  
  ::SendMessage((port->m_hWnd,   WM_COMM_RXCHAR,  
                        (WPARAM)   RXBuff,LPARAM   port->m_nPort);  
            }  
          程序中改变串口时时用init()  
  !!!!!!!!当接收大量数据时,有时程序停在SendMessage处,界面没反映。(用PostMessage不行)  
  问题点数:20、回复次数:22Top

1 楼auly403(卡西*丁布)回复于 2004-11-03 08:20:12 得分 0

upTop

2 楼fu256(大圣)回复于 2004-11-11 21:11:54 得分 0

怎么没有高手回答???Top

3 楼woweijunge(花弄影)回复于 2004-11-11 21:50:49 得分 0

你可以借鉴一下子CSerialPort类的写法,改类的源程序在网上可以下载.Top

4 楼fu256(大圣)回复于 2004-11-12 23:41:31 得分 0

woweijunge(花弄影)   :  
        CSerialPort类也有此问题!!!  
   
        请大家帮帮忙!!!!!!!!!!!Top

5 楼qzh1119(大浪淘沙)回复于 2004-11-13 16:04:14 得分 0

upTop

6 楼38062708(土豆精)回复于 2004-11-13 18:43:55 得分 0

SendMessage   容易丢消息,而且会中断程序,建议用   PostMessageTop

7 楼Saimen(沉默是金)回复于 2004-11-13 19:24:51 得分 5

当接收大量数据时,有时程序停在SendMessage处,界面没反映。  
   
  呵呵,我想问题出来了,SENDMESSAGE   是要等对方执行完了才返回的,估计你这条消息的响应函数出了错.  
   
  说不定进了死循环,换角度看问题Top

8 楼fu256(大圣)回复于 2004-11-14 20:23:29 得分 0

void   CComTestMDlg::OnComRec(WPARAM   wp,   LPARAM   lp)  
  {  
  CString   str;  
  str.Format("%X   ",(BYTE)(char)(wp));  
  m_szRec+=str;  
  UpdateData(FALSE);  
  }  
  没有用循环的.Top

9 楼fu256(大圣)回复于 2004-11-14 20:26:05 得分 0

////////////////////////////////////////////  
  SendMessage   容易丢消息,而且会中断程序,建议用   PostMessage  
  ////////////////////////////////////////////  
  会丢数据的!Top

10 楼fu256(大圣)回复于 2004-11-14 20:30:54 得分 0

请大家帮忙!!!!!!!!!!!  
  我发现SENDMESSAGE   后,还没有调用消息响应函数!就死锁了!  
   
  求救!!!Top

11 楼mybios(俊俊哥哥)回复于 2004-11-14 20:41:03 得分 0

线程中不能使用UpdateData(FALSE);的吧??  
  Top

12 楼AthlonxpX86(一坨屎)回复于 2004-11-14 21:25:53 得分 10

bResult   =   ReadFile(port->m_hComm,&RXBuff,   1,&BytesRead,&port->m_ov);  
  我晕,已经不止一个人问到过我这个问题了,你们之间互相抄袭代码???  
  不死才怪,一次一字节,然后就发消息给窗口,你的效率低到极点,如果串口波特率115k你是不是没秒要发送10k个消息给窗口???  
  bResult   =   ReadFile(port->m_hComm,&RXBuff,   comstat.cbInQue   ,&BytesRead,&port->m_ov);  
  然后根据上面的修改你的消息函数Top

13 楼fu256(大圣)回复于 2004-11-14 21:27:21 得分 0

////////////////////////////////////////////////////  
  线程中不能使用UpdateData(FALSE);的吧??  
  ///////////////////////////////////////////////////  
   
  是     消息响应函数     !!!  
   
  在线等高手  
  在线等高手  
  在线等高手  
  在线等高手Top

14 楼fu256(大圣)回复于 2004-11-14 22:19:30 得分 0

to:   AthlonxpX86(桃源村)    
          你的方法不行!!!  
        虽然处理次数少了,但问题依然存在,SENDMESSAGE   后,还没有调用消息响应函数!就死了!  
         
        在线等高手  
  Top

15 楼AthlonxpX86(一坨屎)回复于 2004-11-15 17:16:08 得分 0

那就应该是你的窗口问题,检查看看你的窗口中是否有什么代码使自己停止响应消息,另外建议你不要学CSerialPort类那样用消息同志窗口的方法接受数据,因为Windows的消息机制并不是实时的,有时甚至会丢失,因此你用堵塞方式的SENDMESSAGE有时是不能成功的,比如托动一下窗口可能就会使你的这种方式的程序死掉Top

16 楼fu256(大圣)回复于 2004-11-15 23:44:52 得分 0

to:   AthlonxpX86(桃源村)    
          请问你有什么好建议!请多多指教!  
          我想写一谢通用的类,如串口类,socket类,你说用消息不好,用回调函数\虚函数怎么样?  
          我的QQ:86363405           Email:86363405@qq.com  
          谢谢!!!Top

17 楼fu256(大圣)回复于 2004-11-16 03:30:23 得分 0

我用虚函数的方式重写了一下(在原SendMessage处调用虚处理函数).  
    问题明显减轻.    
   
      测试环境         发送数据   325/s                    
  -----------------------------------------------------------------------------------        
    方式                       操作                                 操作N次数出错                   问题  
    消息       运行时改变串口或程序退出             N=10至20                 SENDMESSAGE   后,还没调用消息响  
                                                                                                              应函数!就死了!  
  虚函数     运行时改变串口或程序退出             N=100至200             虚处理函数中向列表添加数据时死Top

18 楼kikyang(紫辰)回复于 2004-11-16 03:49:48 得分 5

http://home.ict.nl/~ramklein/Projects/Serial.html    
   
  看下这个类,应该比CSerialPort要更好一些。  
  Top

19 楼AthlonxpX86(一坨屎)回复于 2004-11-16 10:29:24 得分 0

简单说就是异步串行多线程  
  将SendMessage换成SetEvent(),在你要处理数据的线程中等待这个信号(处理完数据就等待这个信号,有信号就接收数据然后处理数据),当然comstat.cbInQue   要足够大后才引起数据传输,这是为了效率,这也是异步操作的思想所在,每次1字节的话就失去异步操作的真正意义Top

20 楼fu256(大圣)回复于 2004-11-20 20:26:06 得分 0

我想做成通用的类!  
  现在用虚函数+主意线程同步=基本稳定!  
  请大家提供更好的方法!   谢谢!!  
  Top

21 楼fu256(大圣)回复于 2004-11-22 12:25:39 得分 0

请大家关注Top

22 楼fu256(大圣)回复于 2004-11-23 19:53:56 得分 0

请高手关注  
  Top

相关问题

  • 怎样在线程中使用串口通信?
  • 串口通信与mscomm控件使用高手请进!
  • 使用 天遥 的串口通信程序产生的问题
  • 串口通信2000下不能使用问题
  • 使用API进行串口通信的问题?
  • 使用多线程,其中一个来负责串口通信
  • 串口通信
  • 串口通信
  • 关于spcom控件的使用!请串口通信高手指教!先谢@!
  • 串口通信中CSerialPort类的使用问题(急!!!)(答者有分)

关键词

  • 函数
  • 线程
  • 消息
  • 数据
  • bcomopen
  • sendmessage
  • 串口
  • 调用
  • heventarray
  • hshutdownevent

得分解答快速导航

  • 帖主:fu256
  • Saimen
  • AthlonxpX86
  • kikyang

相关链接

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

广告也精彩

反馈

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