小弟现在碰到了一个串口通信的问题,希望能得到大虾们的指点!
我是用异步方式打开串口,并用辅助线程来监测串口事件(EV_RXCHAR--第一个字符到达串口是触发),我在辅助线程里做了如下工作:1 先用WaitCommEvent函数等待触发(因为是异步,所以用WaitForSingleObject函数。我测试了,这一步应该是完全正确的。2 接下来,我就用ClearCommError(hCom, &dwErrorFlags, &ComStat );
dwLength = ComStat.cbInQue 来判断到缓冲区的数据有多少,可是每次这个dwLength都只有8个字节,小弟我不知道为什么?(我真是搞不懂啊,苦啊!)3再接下来我就用ReadFile函数读,而且我用ReadFile函数(异步的读)读数据的时候:fReadStat = ReadFile(hCom,lpBuffer,1000,&dwBytesRead, &ComReadFileOVERLAPPED);
fReadStat总是马上返回TRUE(函数根本不管有没有完成我要让他读取的1000个字节的数据);ReadFile函数根本没有在后台进行读操作,而且读进来显示的数据就是8个字节。我的想法:按照我的理解,如果我让ReadFile函数去读1000个字节,(而假使现在到达缓冲区的数据并没有1000个字节的话)那函数不能马上读到1000个字节,那么他应该在后台等待数据的到来(为了能读到1000个字节);直到串口设置的超时产生他才不读。小弟不知道我的想法对不对,而且还是恳求大虾们给我解决点问题啊,为什么我读进来的数据只有8个字节啊!(真是苦啊!)小弟感激不尽!
分一定给啊!!

解决方案 »

  1.   

    To:所有热心的人
    我现在的问题是:当串口里有第一个字节传过来的话,我这个WaitForSingleObject函数就会返回(就是程序知道已经有数据要传过来,但不知道到底有多少数据已经传过来了),接下去我就用ClearCommError(hCom, &dwErrorFlags, &ComStat );
    dwLength = ComStat.cbInQue 来判断到缓冲区的数据有多少,可是经过我的测试,每次的dwlength都是8(我不知道是为什么),而且接下去更怪的是我让ReadFile函数要读的字节根本是大于8的(我用的是1000),而且我的ReadFile函数是异步的读数据的,所以按照道理应该是ReadFile函数是返回false的,可他却返回true( ReadFile函数认为读8个字节就算完成工作了)按照我的思路接下去才去调用GetOverlappedResult函数(最后一个参数是TRUE),可GetOverlappedResult函数根本就是没有运行到,因为我的ReadFile函数返回了true.
    这个问题我真的不知道是为什么,我知道我的程序应该没有大的问题,可能就是这么一点点的小的错误,希望大虾们能给我指点啊!
    我谢谢你们啦!
      

  2.   

    哎,痛苦的人,我救你一次吧。
    static char buf[1000];
        static char str[1000];
    //    char recv[1000];
    //    char recvbuf[1000];
        static int i=0;
        static int n=0;
        int j=0; 
        int nLength;
    CString string;
    CComm comm;
        if(!comm.bConnected ||(wParam & EV_RXCHAR)!=EV_RXCHAR) // 是否是EV_RXCHAR事件?
        {
          SetEvent(comm.hPostMsgEvent); // 允许发送下一个WM_COMMNOTIFY消息
          return 0L;
        }
        nLength=comm.ReadComm(buf,1000);
        n=n+nLength;  CComTestApp* pApp = (CComTestApp*)AfxGetApp( );
    pApp->sumRecvLen +=nLength; //在状态条中显示收到的字符数
    CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
    int nIndex=pFrame->m_wndStatusBar.CommandToIndex(IDS_RECVNUM);
    CStatusBar* pStatus=&pFrame->m_wndStatusBar;
    if(pStatus)
    {
    string.Format("接收字节数: %d",pApp->sumRecvLen);
    pStatus->SetPaneText(nIndex,string);
    }

    CCShowData ShowData;

        for(;i<n;i++,j++)//一块收,不是8个8个收
        {  
    str[i]=buf[j];
        } 
    实在不行,明天给你原程序。
    哎,谁又能帮帮我呢?
      

  3.   

    2000 下 readfile 是总返回true的
    按照我的理解,如果我让ReadFile函数去读1000个字节,(而假使现在到达缓冲区的数据并没有1000个字节的话)那函数不能马上读到1000个字节,那么他应该在后台等待数据的到来
      ~~~~~~~~~~~~~~~~~~~~异步是不会等待的。
    8 其实只有一个字符。数据位你定的是8位。每来一个字符便查询。当然只有一个了。建议你一个字符一个字符的接收数据
      

  4.   

    To:啊蒙
       你好!
       2000 下 readfile 是总返回true好象在msdn里没说啊,大虾你确认吗?   我知道异步ReadFile函数是不会等待的,但我想当我我让ReadFile函数去读1000个字节,(而假使现在到达缓冲区的数据并没有1000个字节的话)那函数不能马上读到1000个字节,那么他应该立刻返回false(ReadFile函数是立刻返回的),假使按照您的说法他在2000里总是返回true的话 ,那ReadFile函数的第三个参数(我要他读的字节数)设在这里岂不是没用了啊?(函数假如现在没有读到我要他所读到的字节数,他也返回true?)(我是菜鸟啦!休见怪)
      

  5.   

    咱们有同样的问题,我刚刚解决,试试在执行前
    ClearCommError(hCom, &dwErrorFlags, &ComStat );
    dwLength = ComStat.cbInQue
    在上sleep(1000);
    因为异步方式,当一个事件来了后 WaitForSingleObject立即返回,这时执行ClearCommError(hCom, &dwErrorFlags, &ComStat );
    dwLength = ComStat.cbInQue
    串口中可能只送来了几个字符,所以读数是不正确的,加上sleep(1000)等一下
    就好了,祝好运。
            对了,有没有用,都请留个说,我分析分析。