使用FTDI和ReadFile进行串行通信的延迟

时间:2018-09-17 13:24:42

标签: c++ visual-studio serial-port microcontroller ftdi

在通过C / C ++(Visual Studio)中的虚拟通信端口与FTDI设备通信时,我注意到了一个奇怪的延迟。

我向设备发送一条命令(11个字符),该命令返回一个字符串(18个字符),大约需要5毫秒才能完成(发送+接收)。通讯以57600波特进行。

经过一些测试,我发现在我的计算机上执行此代码可以花很长时间(5ms),而在其他计算机上执行该代码大约需要15到20 ms。奇怪的是,当通过C#使用System.IO.Ports与FTDI通信时,这种效果不会出现(无论PC在执行什么,我总是获得5ms的执行时间)。 在这个特定应用程序中,时间至关重要,因此删除这些额外的毫秒非常重要。

端口缓冲区的延迟时间已手动设置为1ms(设备管理器)。

我认为这应该与打开端口的方式有关,但是我已经测试了许多解决方案,但没有任何效果。

这是我用来打开端口的代码:

hCom = CreateFile(DevPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if ( hCom==INVALID_HANDLE_VALUE) {
    CloseHandle(hCom);
    hCom = NULL;
    return false;
} else {
    if (!SetupComm(hCom,2048,2048)) {
        CloseHandle(hCom);
        hCom = NULL;
        return false;
    }

    try {

        dcb.DCBlength = sizeof(DCB);
        GetCommState(hCom, &dcb);

        //No Flow control
        dcb.BaudRate = CBR_57600;
        dcb.ByteSize = 8;         // Setting ByteSize = 8
        dcb.StopBits = ONESTOPBIT;// Setting StopBits = 1
        dcb.Parity   = NOPARITY;  // Setting Parity = None
        dcb.fBinary = TRUE;
        dcb.fParity = FALSE;
        dcb.fOutxCtsFlow = FALSE;
        dcb.fOutxDsrFlow = FALSE;
        dcb.fDtrControl = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = FALSE;
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
        dcb.fTXContinueOnXoff = FALSE;
        dcb.fOutX = FALSE;
        dcb.fInX = FALSE;

        if(!SetCommState(hCom, &dcb)) {
            CloseHandle(hCom);
            hCom  = NULL;
            return false;
        }
    } catch (std::string strCatchErr) {
        CloseHandle(hCom);
        hCom = NULL;
        return false;
    }

    CommTimeouts.ReadIntervalTimeout = MAXDWORD;
    CommTimeouts.ReadTotalTimeoutConstant = 0;
    CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    CommTimeouts.WriteTotalTimeoutConstant = 40;
    CommTimeouts.WriteTotalTimeoutMultiplier = 0;

    if(!SetCommTimeouts(hCom, &CommTimeouts)) {
        CloseHandle(hCom);
        hCom = NULL;
        return false;
    }

    //purge port buffers
    PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);

    return true;

使用普通的ReadFile和WriteFile指令完成对端口的读写过程:

DWORD BytesRead = 0;
DWORD TotalBytesRead = 0;
DWORD BytesToRead = 20;
DWORD bytesWritten = 0;
BOOL bSuccess;
char rxbuffer[1024];
char * InBuffer;
int fRun = 1;

//Send data
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_RXABORT);
WriteFile(hCom, "TESTCMD001\n", (DWORD)11, &bytesWritten, NULL);

//receive data
InBuffer = &rxbuffer[0];

while(fRun) {
    BytesRead = 0;
    bSuccess = ReadFile(hCom, InBuffer, BytesToRead, &BytesRead, NULL);
    if ( bSuccess==TRUE ) {
        if (BytesRead>0) {
            TotalBytesRead += BytesRead;
            rxbuffer[TotalBytesRead] = '\0';
            InBuffer = &rxbuffer[TotalBytesRead];
            if ( strchr(rxbuffer, '\n')!=NULL ) fRun = 0;
        } //IF_BytesRead>0
    } //IF_ReadFile
}

注意! ->这是代码的简化版本,因此可能会出错。

有人以前经历过类似的事情吗? 任何帮助将不胜感激。

0 个答案:

没有答案