繁体   English   中英

串口无法读取完整的传输

[英]Serial port not reading complete transmission

我试图将Teunis van Beelen的Rs232库修改为从轮询到事件驱动且不重叠以适合我的项目。 RS232库

我希望每200毫秒接收一次数据块(大约100到200个字符)。

我遇到的问题是接收到的数据非常不一致,它在随机点被切断,并且不完整。

我希望ReadFile()仅在读取整个数据块后才返回。

我觉得问题出在超时设置上,因为通过更改数字我得到了不同的结果,但是我无法正确完成,到目前为止,我最好的结果是将所有超时值都设置为0,并期望ReadFile() 150字节,这样,除非读取150个字符,否则ReadFile()不会返回,但这在几次传输后就变得不同步,因为我不知道会有多少数据。

这些是Teunis代码中轮询功能的主要更改,除了超时设置外,所有其他设置均保持不变:

//Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port
 DWORD dwError  = 0;
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port
//SetCommMask sets the desired events that cause a notification.
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){
    printf("SetCommMask Error");
    dwError = GetLastError();
    // Error setting com mask
    return FALSE;
}
//WaitCommEvent function detects the occurrence of the events.
DWORD dwCommEvent;
for( ; ; )
{
    //wait for event to happen
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL))
    {
        if(ReadFile(Cport[comport_number], buf, 1, (LPDWORD)((void *)&n), NULL)){
            //Byte has been read, buf is processed in main
        }
        else{
            //error occoured in ReadFile call
            dwError = GetLastError();
            break;
            }
    else{
        //error in WaitCommEvent
        break;
    }

    break;  //break after read file
}

尝试2(如在串行com上MSDN文章所建议的那样)使用Do While在缓冲区中的每个字符之间循环,该方法也未产生任何好的结果。

DWORD dwError  = 0;

/*
Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port
*/
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port
//SetCommMask sets the desired events that cause a notification.
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){
    printf("SetCommMask Error");
    dwError = GetLastError();
    // Error setting com mask
    return FALSE;
}
//WaitCommEvent function detects the occurrence of the events.
DWORD dwCommEvent;
for( ; ; )
{
    //wait for event to happen
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL))
    {
        //Do while loop will cycle ReadFile until bytes-read reach 0,
        do{
        if(ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)){
            //Byte has been read, buf is processed in main
        }
        else{
            //error occoured in ReadFile call
            dwError = GetLastError();
            break;
            }
            }while(n);
        }
    else{
        //error in WaitCommEvent
        break;
    }
    break;  //break after read file
}

我想知道以重叠模式重写代码是否可以改善情况,但是我看不到优点,因为我不需要多线程。 任何建议都很好!

谢谢。

ReadFile无法检测什么是“数据块”。 您不应期望它了解您的数据或数据时间。 解决此问题的唯一方法是让您处理自己提供的所有信息,并利用自己对数据的了解将其分为“块”以进行进一步处理。 如果得到部分块,请保留它,并在下一次读取时附加到它后面。

无需调用WaitCommEvent来获取数据。 ReadFile将等待数据。 但是给它一个适当大小的缓冲区,一次要请求一个以上的字节。 仅调用一个字节是非常低效的。 选择请求的计数和超时,以便无论是否有数据,ReadFile都将在可接受的时间内返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM