如何了解数据是否进入串行端口缓冲区 [英] How to understand if data comes to serialport buffer

查看:182
本文介绍了如何了解数据是否进入串行端口缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要从串行端口接收数据.我使用C ++,Visual Studio 2010和Windows.h库编写了一个程序.
我从电子卡接收了所有数据,我们通过握手进行通信...

我已经对握手进行了必要的调整,如下所示:

need to receive data from serialport. I wrote a program with Windows.h library, using C++, Visual Studio 2010..

I receive all datas from an electronic card, we communicate by handshaking...

I''ve made the necessary adjustments for handshaking as shown below:

DCB dcb;

dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = TRUE;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fNull = FALSE;
dcb.fOutX = FALSE;
dcb.fInX =  FALSE;


然后,我将RTS和DTR位置1,以表示我准备接收数据,如下所示.这就是我调用的函数:


Then I set RTS and DTR bits to say I''m ready to receive data as shown below. This one is the function I call:

bool ImSeriAygit::setHardwareControl(bool hardwareControl)
{
    DCB dcb;

    myHardwareControl = hardwareControl;

    if (getStatus() != STATUS_OPEN) // if closed
        return true;

    if (!GetCommState(myPort, &dcb)) // Default port
    {
        printf("ImSeriAygit::setHardwareControl: Could not get port Data.\n");
        return false;
    }

    if(myHardwareControl == 0) /* set control lines */
    {
        dcb.fRtsControl = RTS_CONTROL_ENABLE; // Enable RTS 
        dcb.fDtrControl = DTR_CONTROL_ENABLE; // Enable DTR
    }

    else
    {
        dcb.fRtsControl = RTS_CONTROL_DISABLE; // rts disable
        dcb.fDtrControl = DTR_CONTROL_DISABLE; // dtr disable
    }

    if (!SetCommState(myPort, &dcb)) 
    {  
        printf("ImSeriAygit::setHardwareControl: Could not set port Data.\n");
        return false;
    }  

  return true;
}


这就是我的称呼:

ser.setHardwareControl(false); //ser是ImSeriAygit对象.
之后,我使用ReadFile函数读取串行端口,如下所示:


This is how I call it:

ser.setHardwareControl(false); // ser is the ImSeriAygit object.
After that I read the serial port using ReadFile function as shown below:

int ImSeriAygit::read(const char *data, unsigned int size, 
                      unsigned int msWait) 
{
    COMSTAT stat;

    unsigned long ret;
    unsigned int numToRead;

    if (myPort != INVALID_HANDLE_VALUE && myStatus == STATUS_OPEN)
    {
        if (!ClearCommError(myPort, &ret, &stat)) 
            return -1;

        if (stat.cbInQue == 0) 
            return 0;

        if (stat.cbInQue > size) 
            numToRead = size;
        else
            numToRead = stat.cbInQue;

        if(get

        if (ReadFile( myPort, (void *)data, numToRead, &ret, NULL))
        {
            return (int)ret;
        }
        else 
        {
            printf("ArSerialConnection::read:  Read failed.\n");
            return -1;
        }
    }

    printf("ArSerialConnection::read: Connection invalid.\n");
    return -1;
}


当我调试程序时,我意识到有时读取的数据已损坏,实际上是适当的形式,但是有时没有损坏...

我想我虽然握手却不能正确捕获传入的数据...

有什么建议可以知道数据是否及时到位吗?最好的问候...


When I debug my program, I realised that sometimes the data I read is corrupted, which is in fact in a suitable form, but sometimes there is no corruption...

I guess I don''t catch the incoming data properly although I''m handshaking...

Any suggestions to know if the data comes in time? My best regards...

推荐答案

您正在调用ClearCommError(),但未检查错误值.也许可以帮助您发现问题.

您正在检查是否有更多的可用字节超出缓冲区可以容纳的字节数.那挺好的.但是,如果发生这种情况,您应该立即再次调用receive函数.

您可能正在将布尔值与0进行比较,并使用相反的逻辑:
You are calling ClearCommError() but did not check the error value. Maybe that will help you finding the problem.

You are checking if there are more bytes available than your buffer can hold. That''s good. But if this happens, you should call the receive function again immediately.

You are probably comparing a boolean value with 0 and uses reversed logic:
// Parameter hardwareControl is bool
bool ImSeriAygit::setHardwareControl(bool hardwareControl)
{
...
// Copy parameter to member var. Really necessary? 
// Is myHardwareControl also of type bool?
    myHardwareControl = hardwareControl;
...
// Compare a boolean value (or is myHardwareControl of type int or other?)
//  with 0. Using 'false' would be better.
// But this is reversed logic: Setting control lines when value is false.
    if(myHardwareControl == 0) /* set control lines */



您没有显示您稍后要切换DTRRTS,因此向另一端发出信号,表明您始终准备好接收数据.当接收缓冲区已满时,这可能导致数据丢失.当系统负载较高(例如磁盘和网络传输)时,即使串行通信速度很慢也可能会发生这种情况.您可以使用RTS_CONTROL_HANDSHAKEDTR_CONTROL_HANDSHAKE来避免缓冲区溢出.

如果连接的系统不仅响应请求,而且自身发送数据,则应创建一个工作线程以使用重叠的IO接收数据.



You did not show that you are toggling DTR and RTS later, thus signaling the other end that you are always ready to receive data. This can result in data loss when the receive buffer is full. This may even happen with rather slow serial communication when the system load is high (e.g. disk and network transfers). You may use RTS_CONTROL_HANDSHAKE and DTR_CONTROL_HANDSHAKE to avoid buffer overruns.

If the connected system is not only responding to requests, but sending data by itself, you should create a worker thread for receiving data using overlapped IO.


这篇关于如何了解数据是否进入串行端口缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆