是这样的,公司需要一个程序来和串口通讯,
打开串口事件:void OpenCom();
向串口写检查状态命令:bool WriteCheckCMD(...);在打开串口时需要向设备发送一条命令来检查设备的状态,
但是,经常向串口写检查命令会失败,(不是每次都是,是经常!)
做法如下:
OpenCom();
Sleep(n);//加上延时也会有同样的情况,
WriteCheckCMD(...);
不知道为什么,另外,如果把WriteCheckCMD放在另外一个按钮事件当中就不会,每次都成功,
这是为什么?麻烦大家看看

解决方案 »

  1.   

    打开串口函数:BOOL CCESeries::OpenPort(CWnd* pPortOwner,
     UINT portNo ,
     UINT baud ,
     UINT parity ,
     UINT databits ,
     UINT stopbits
     )
    {
    DCB commParam;
    TCHAR szPort[15];

    if (m_hComm != INVALID_HANDLE_VALUE)
    {
    return TRUE;
    }
    ASSERT(pPortOwner != NULL);
    ASSERT(portNo > 0 && portNo < 255); wsprintf(szPort, L"COM%d:", portNo); m_hComm = CreateFile(
    szPort,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    0,
    NULL 
    );

    if (m_hComm == INVALID_HANDLE_VALUE)
    {
    TRACE(_T("CreateFile return invalid handle."));
    return FALSE;

    }

    if (!GetCommState(m_hComm,&commParam))
    {
    return FALSE;
    }

    commParam.BaudRate = baud;
    commParam.ByteSize = databits;
    commParam.Parity = NOPARITY;
    commParam.StopBits = stopbits;
    if (!SetCommState(m_hComm, &commParam))
    {
    TRACE(_T("SetCommState error"));
    return FALSE;
    }
        
    COMMTIMEOUTS CommTimeOuts;
    GetCommTimeouts (m_hComm, &CommTimeOuts);
    CommTimeOuts.ReadIntervalTimeout = 100;  
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;  
    CommTimeOuts.ReadTotalTimeoutConstant = 500;    
    CommTimeOuts.WriteTotalTimeoutMultiplier = 10;  
    CommTimeOuts.WriteTotalTimeoutConstant = 1000;  

    if(!SetCommTimeouts( m_hComm, &CommTimeOuts ))
    {
    TRACE( _T("SetCommTimeouts return error.") );
    return FALSE;
    }

    m_pPortOwner = pPortOwner;

    SetCommMask (m_hComm, EV_RXCHAR);

    SetupComm(m_hComm,4096,4096);

    PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);

    m_hReadCloseEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//TRUE
    m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

    m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);//Run thread immediately after creating.

    m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);

    TRACE(_T("Open com port success!"));

    return TRUE;
    }
    写串口函数:BOOL CCESeries::WriteCommData(HANDLE hComm,const BYTE *buf,DWORD bufLen)//Add 20080219
    {
    DWORD dwNumBytesWritten;
    DWORD dwHaveNumWritten =0 ; 

    ASSERT(hComm != INVALID_HANDLE_VALUE);
    do
    {
    if (WriteFile (hComm,
    buf+dwHaveNumWritten,
    bufLen - dwHaveNumWritten,          
    &dwNumBytesWritten,
    NULL))
    {
    dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;

    if (dwHaveNumWritten == bufLen)
    {
    break;
    }
    Sleep(10);
    }
    else
    {
    return FALSE;
    }
    }while (TRUE);

    return TRUE;
    }
      

  2.   

    你的那个WriteThreadFunc线程是干嘛的?是不是也向串口里写数据?怀疑是这个线程和WriteCheckCMD(...); 冲突。
      

  3.   

    WriteThreadFunc
    这些不用管的,和那些没关系,我已经没用那些线程了,
    直接用WriteCommData(=WriteCheckCMD)进行写串口数据的,
      

  4.   

    sleep会使主程序停顿,所以 将sleep用其他方法,比如时间差比较好,在计算时间差的时候用peekmessage等函数让出系统时间。
      

  5.   

    按照你的函数(没细看),你只需要这样就可以了,不要Sleep。
    if (OpenCom())
        WriteCheckCMD(...); 
      

  6.   

    谢谢上面的二位,To:jennyvenus,
    我会试试您的方法,
    To:Mackz,
    的确,我开始也以为这样可以的,
    不用延时什么的,
    但是,我在Delphi里面也试了一下,(还是用Delphi中的控件spcomm来试的),也不行。
    经常写串口失败,所以,我一直感觉好像有哪里不对,按理论上来说,打开串口--发送数据,这个应该没问题,但是,只要放在一个事件里处理就会出现这个问题,
      

  7.   

    g____hComm = CreateFile(
    ( LPCTSTR )commname,
    GENERIC_READ | GENERIC_WRITE,
    0, //share mode: no share
    NULL, //securiy attributes
    OPEN_EXISTING, //Open disposition
    FILE_FLAG_OVERLAPPED,
    NULL );
    /////////////////////////////////////////按俺的习惯,串口一般用异步方式打开,重叠IO操作http://www.impcas.ac.cn/usr/yuanyj/vcpptutorial/chap12_3.htm这个贴子说的不错。
      

  8.   

    多谢 Jennyvenus,俺您所说,我改了打开串口代码:
    m_hComm = CreateFile(
    szPort,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//0
    NULL 
    );和
    m_hComm = CreateFile(
    szPort,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,//0
    NULL 
    );
    但是,最后效果都一样,
    还是有时行,有时不行,
    郁闷,
      

  9.   

    你不会是usb转串口吧?设备本身问题?
      

  10.   

    不是,
    正常的串口,
    不过,是Windows CE上的串口!
    不是PC上的,
      

  11.   

    重金诚聘C++
    http://topic.csdn.net/u/20080227/14/8bce0844-bd15-42f0-9cda-a343d5d6601b.html?seed=2111206245