首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

再请问大侠

2013-04-20 
再请教大侠我在百度上找了个串口发送和接受的例子:for() {bResult ::ClearCommError(hComm,&dwError,&

再请教大侠
我在百度上找了个串口发送和接受的例子:

for(;;)
 {
   bResult = ::ClearCommError(hComm,&dwError,&comstat);
    if(comstat.cbInQue == 0)
      continue;
      //if(!::SetCommMask(hComm,EV_RXCHAR))
         //continue;
    if(bRead)
    {
      bResult = ::ReadFile(hComm,
                         &RXBuff,
                         1,
                         &BytesRead,
                         &m_ov);
可是当使用ClearCommError函数时,得到的cbInque总是为0,导致死循环。
然而使用SetCommMask函数可以得到缓冲区已经接收到数据 了,只是用下面的ReadFile函数读出的数据不正确,这个又是咋回事呢。。。。求解
[解决办法]
剛才我大概看一下...因為其一是以永久循環迴路來做例子...其二是使用 Communicate 的 Overlapped 模式...所以在調試檢測通訊狀態或讀寫時並不會等待完成函數就直接離開...當然會導致死循環囉~ 實際的作法必須以計時器或多線程方式來輪詢......

SetCommMask 與 WaitCommMask 應該是匹配使用的...你所列出的例子其敘述並不是那麼完整...建議你把完整的例子給列出必較容易看出問題喔......
[解决办法]
我给你一个串口程序你参照下  前不久刚写的 没问题
void __fastcall TMainForm::CreatComm()
{
    Comm.hCom = CreateFile( g_strCommPort.c_str(),GENERIC_READ
[解决办法]
GENERIC_WRITE,
                                0,
                                NULL,
                                OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED,
                                NULL);

    if ( Comm.hCom == INVALID_HANDLE_VALUE )
    {
        //ShowMessage("串口打开错误!");


        Application->MessageBoxA("没有找到设备!", "错误!", MB_OK
[解决办法]
MB_ICONERROR);
        exit(3);
    }
    if(Comm.hRecvEvent != NULL)
    {
        ResetEvent(Comm.hRecvEvent);
    }

    if(!SetCommMask(Comm.hCom,EV_RXCHAR))
    {
        ShowMessage("通信事件设置错误!");
        CloseHandle(Comm.hCom);
        return;
    }
    if(!InitCom())
    {
        ShowMessage("串口初始化错误!");
        CloseHandle(Comm.hCom);
        return;
    }
//    if(!InitTimeCom())
//    {
//        ShowMessage("串口超时设置错误!");
//        CloseHandle(Comm.hCom);
//        return;
//    }
//    Comm.hRecvEvent = CreateEvent(NULL,true,false,NULL);
    if(!SetupComm(Comm.hCom, 128, 128))
    {
        ShowMessage("串口缓冲区设置错误!");
        CloseHandle(Comm.hCom);
    }
    //清空输入输出缓冲区
    if(!PurgeComm(Comm.hCom, PURGE_RXABORT 
[解决办法]
PURGE_TXABORT 
[解决办法]
PURGE_TXCLEAR 
[解决办法]
 PURGE_RXCLEAR ))
    {
        ShowMessage("串口缓冲区清理错误!");
        CloseHandle(Comm.hCom);
    }             
    m_hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadProc,0,0,NULL);//创建监听串口数据线程
}
bool __fastcall TMainForm::InitCom()
{
    //串口初始化
    DCB dcb;
    GetCommState(Comm.hCom,&dcb);
    dcb.BaudRate = StrToInt(g_strBaud);
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT ;
    return (SetCommState(Comm.hCom,&dcb));
}
bool __fastcall TMainForm::InitTimeCom() //超时设置
{
    COMMTIMEOUTS TimeOuts;
    GetCommTimeouts(Comm.hCom, &TimeOuts);
    TimeOuts.ReadIntervalTimeout = 0;
    TimeOuts.ReadTotalTimeoutMultiplier = 0;
    TimeOuts.ReadTotalTimeoutConstant = 0;
    TimeOuts.WriteTotalTimeoutMultiplier = 50;
    TimeOuts.WriteTotalTimeoutConstant = 2000;
    return (SetCommTimeouts(Comm.hCom, &TimeOuts)) ;   


}   

写数据
void __fastcall TMainForm::suiButton1Click(TObject *Sender)
{
    DWORD  dwBytesWriten;
    DWORD dwBytesSend;
    OVERLAPPED osWrite;
    Byte btWrite[64];

    memset(&osWrite, 0 ,sizeof(OVERLAPPED));

    Byte btTitle[] = {0x7E,0x81,0x00,0x40,0x86,0x00,0x00,0x00,   //0x40 总字节数
                      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
                      0x00,0x00,0x00,0x10 // 0x10写32个字节 16个字
                      };

    Byte btEnd[] = {0x0D, 0x0A};


    memset(btWrite, 0 ,64);
    for(int i = 0; i<28; i++)
    {
        btWrite[i] = btTitle[i];
    }
    for(int i = 0; i<32; i++)
    {
        btWrite[i+28] = m_btData[i];
    }

    Byte btCRC = GetCRC(btWrite,64);
    btWrite[60] = 0x00;
    btWrite[61] = btCRC;
    btWrite[62] = btEnd[0];
    btWrite[63] = btEnd[1];

    WriteFile(Comm.hCom, btWrite, sizeof(btWrite), &dwBytesWriten, &osWrite);

    if(ERROR_IO_PENDING== GetLastError())
    {
        GetOverlappedResult(Comm.hCom, &osWrite, &dwBytesWriten, true );
    }

}

读数据
   DWORD dwRead, dwEvMask, dwTransfer, dwErrorFlags;
    memset(&Comm.osRead, 0, sizeof(OVERLAPPED));
    Comm.osRead.hEvent = CreateEvent(NULL,true,false,NULL);
    while(1)
    {
        if(!WaitCommEvent(Comm.hCom, &dwEvMask, &Comm.osRead))
        {
            //ERROR_IO_PENDING错误:重叠I/O返回的标志。表示现在等待I/O,稍后就会返回
            if(ERROR_IO_PENDING == GetLastError())
                GetOverlappedResult(Comm.hCom,&Comm.osRead,&dwTransfer,true);
        }
        if((dwEvMask & EV_RXCHAR)==EV_RXCHAR)
        {
            ClearCommError(Comm.hCom,&dwErrorFlags,&Comm.ComStat);
            if(Comm.ComStat.cbInQue > 0)


            {
                SendMessage(g_hForm,WM_COMDATA,NULL,NULL);
            }
        }
    }

热点排行