代码之家  ›  专栏  ›  技术社区  ›  Zotto

从串行端口C++Windows读取字节

  •  1
  • Zotto  · 技术社区  · 8 年前

    嘿,我正在尝试连接到我的windows机器上的xbees。我能够在AT模式下通过协调器写入终端设备,并且可以看到流式传输到我的XCTU控制台的数据。然而,我很难理解如何读取传入的数据。

    我目前使用的代码如下。基本上,唯一关键的部分是最后5行左右(特别是读写文件行),但我将发布所有内容,以便彻底了解。如何读取通过com端口发送到xbee的数据?我发送的数据只是0x00-0x0F。

    我想我误解了读取文件的功能。我假设我发送给xbee的比特存储在一个缓冲区中,一次只能读取一个。是这样吗?或者我需要写入整个字节,而不是读取可用的数据吗?如果我的思路让人困惑,我很抱歉,我对串行通信相当陌生。感谢任何帮助。

    #include <cstdlib>
    #include <windows.h>
    #include <iostream>
    using namespace std;
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        int n = 8; // Amount of Bytes to Read
        HANDLE hSerial;
        HANDLE hSerial2;
        hSerial = CreateFile("COM3",GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
        hSerial2 = CreateFile("COM4",GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
        if(hSerial==INVALID_HANDLE_VALUE || hSerial2==INVALID_HANDLE_VALUE){
            if(GetLastError()==ERROR_FILE_NOT_FOUND){
    //serial port does not exist. Inform user.
        cout << "Serial port error, does not exist" << endl;
        }
    //some other error occurred. Inform user.
        cout << "Serial port probably in use" << endl;
        }
    
        DCB dcbSerialParams = {0};
        dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
        if (!GetCommState(hSerial, &dcbSerialParams)) {
            cout << "error getting state" << endl;
        }
        dcbSerialParams.BaudRate=CBR_9600;
        dcbSerialParams.ByteSize=8;
        dcbSerialParams.StopBits=ONESTOPBIT;
        dcbSerialParams.Parity=NOPARITY;
        if(!SetCommState(hSerial, &dcbSerialParams)){
            cout << "error setting serial port state" << endl;
    
        }
    
        COMMTIMEOUTS timeouts = {0};
    
        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier =10;
        timeouts.WriteTotalTimeoutConstant = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;
    
        if (!SetCommTimeouts(hSerial, &timeouts)){
            cout << "Error occurred" << endl;
        }
    
        DWORD dwBytesWritten = 0;
        DWORD dwBytesRead = 0;
        unsigned char oneChar;
        for (int i=0; i<16; i++)
            {
              oneChar=0x00+i;
              WriteFile(hSerial, (LPCVOID)&oneChar, 1, &dwBytesWritten, NULL);
              ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL); // what I tried to do, just outputs white space
            }
    
        CloseHandle(hSerial);
    
    
    
        return 0;
    }
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   tomlogic    8 年前

    在您的声明中:

    ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL);
    

    您需要检查的值 dwBytesRead 看看你是否真的读取了任何字节。也许在连接的一端,您希望一个简单的程序每秒发送一个字节。在另一端,您希望检查可用字节,并在它们进入时转储它们。

    程序中可能发生的情况是,您在很短的时间内填充出站串行缓冲区,没有等待足够长的时间来读回任何数据,然后退出循环并关闭串行端口,很可能是在它完成发送队列数据之前。例如,在 CloseHandle() 呼叫,您可以添加:

    COMSTAT stat;
    
    if (ClearCommError(hCom, NULL, &stat))
    {
        printf("%u bytes in outbound queue\n", (unsigned int) stat.cbOutQue);
    }
    

    在发送完成之前,看看您是否关闭了句柄。