我在程序启动时,把串口打开的过程放到了一个多线程里, 运行时串口可以正常打开,也可以发送数据,但是接收不到设备返回的数据。
要是不放在多线程里,在OnInitDialog里打开串口,就可以正常的发送和接收。怎么才能解决?我是因为要同时打开多个串口,但是如果都放在OnInitDialog里打开,如果有一个串口是无效的那程序就停止在那里了,所以我才想在多线程里同时打开多个串口。不知道这样做对不对,或者还有别的方法??请诸位高手帮帮忙。
这么打开虽然可以正常接收到数据,但是如果COM8是无效的,那就直接弹出错误信息,程序就停了。
BOOL CTestDlg::OnInitDialog()
{
    m_com2.SetCommPort(8);
    m_com2.SetSettings("9600,n,8,1");
    m_com2.SetInputLen(0);
    m_com2.SetInputMode(1);
    m_com2.SetRThreshold(1);
    m_com2.SetInBufferSize(1024); //接收缓冲区
    m_com2.SetOutBufferSize(1024);//发送缓冲区
    m_com2.SetPortOpen(TRUE);
    m_com2.GetInput();    m_com3.SetCommPort(9);
    m_com3.SetSettings("9600,n,8,1");
    m_com3.SetInputLen(0);
    m_com3.SetInputMode(1);
    m_com3.SetRThreshold(1);
    m_com3.SetInBufferSize(1024); //接收缓冲区
    m_com3.SetOutBufferSize(1024);//发送缓冲区
    m_com3.SetPortOpen(TRUE);
    m_com3.GetInput();}这个是我在OnInitDialog里启动多线程打开串口
BOOL CTestDlg::OnInitDialog()
{
    AfxBeginThread(Thread_OpenCom2, this, THREAD_PRIORITY_NORMAL);
}UINT CTestDlg::Thread_OpenCom2(LPVOID lParam)
{
    CTestDlg* p=(CTestDlg*)lParam; // this if(p->m_com2.GetPortOpen())
{
p->m_com2.SetPortOpen(FALSE);
}
p->m_com2.SetCommPort(8);
p->m_com2.SetSettings("9600,n,8,1");
p->m_com2.SetInputLen(0);
p->m_com2.SetInputMode(1);
p->m_com2.SetRThreshold(1);
p->m_com2.SetInBufferSize(1024); //接收缓冲区
p->m_com2.SetOutBufferSize(1024);//发送缓冲区
p->m_com2.SetPortOpen(TRUE);
p->m_com2.GetInput(); return 9999;
}
这么打开的话 同时打开4个 即使有1个串口时无效的也不会影响其它的,但是却不能接收到模块返回的数据了。我是初学者,恳请诸位帮帮忙。问题出现在哪里??

解决方案 »

  1.   

    MSCOMM控件?
    这个控件似乎是收到数据自动发送消息的吧,你要收到消息后,在消息处理函数里去进行接收工作
    而你打开串口后马上紧接着GetInput()是什么意思?打开就已经有数据了?那后来的数据呢?不要了?
    在单线程的情况下,接收串口数据是在串口控件消息响应函数OnComm()中进行接收数据的工作你要在其他线程里打开串口,接收数据,就得处理好读取的问题,要么根据消息去读取,要么就线程死读取(最好是中间sleep一下,不然容易高占用CPU)。
      

  2.   

    你的逻辑很有问题, 首先程序应该只占有 有用的资源。 你打开那么多串口,万一有别的设备怎么办? 没意思, 也没效率。其实正规的通用的方法是: 你从com1开始试, 是否打开, 能打开, 然后给仪器发一个命令,如果在规定的时间内从收到正确的响应包, 则就用此串口, 如果超时,重试n次(一般为3次),还是收不到正确命令, 切换到下一个串口。。
    打开正确的串口后,后面的事情就很简单了。
      

  3.   

    是这个意思
    自己建立一个通信机制来判断设备连接
    另外打开串口会阻塞么?
    为什么在OnInitDialog里不行呢
      

  4.   

    把打开串口的操作放到try catch 里面,
    这样在串口不存在或是串口不可用的时候,你去打开程序就不会down掉了。
    这是我以前的代码,和这个类似:
    try {
    m_mscomm.put__CommPort(m_portNum);
    m_mscomm.put_InBufferSize(256); //设置输入和输出缓存的大小
    m_mscomm.put_OutBufferSize(256);
    if(!m_mscomm.get_PortOpen())
    {
    m_mscomm.put_PortOpen(TRUE);
    m_mscommable = TRUE;
    }
    else
    {
    m_mscommable = FALSE;
    }

    m_mscommable = true;
    }  catch(COleDispatchException *e)
    {
    m_mscommable = false;
    CString port; if(e->m_dwHelpContext == 8005)
    { port.Format(_T("串口COM%d已被占用"), m_portNum);

    else if(e->m_dwHelpContext == 8002){
    port.Format(_T("串口COM%d不存在"), m_portNum);
    }
    else {
    port.Format(_T("串口COM%d打开时操作不合法"), m_portNum);
    } MessageBox(port, _T("提示"), MB_OK | MB_ICONWARNING );
    return false;
    }
      

  5.   


    感谢回答
    打开串口后马上紧接着GetInput()
    是清空缓存空间用的,例子上也是这么写的,不是我乱加上的。