我试图修改Teunis van Beelen的Rs232库,从Polling到事件驱动和非重叠以适合我的项目。 RS232 Library
我希望每200毫秒收到一些数据块(大约100到200个字符)。
我遇到的问题是收到的数据非常不一致,它在随机点被切断,而且不完整。
我希望ReadFile()只在读完一整个数据块后才能返回。(或其他类似的东西)
我觉得问题在于超时设置,因为通过改变数字我会得到不同的结果,但我不能正确,我的最佳结果到目前为止已将所有超时值设置为0并让ReadFile ()期望150个字节,这样ReadFile()不会返回,除非它读取150个字符,但这只是在几次传输后失去同步,因为我不知道要预期多少数据。
这些是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
}
按照MSDN article on serial com的建议尝试2使用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
}
我想知道在重叠模式下重写代码是否会改进,但我没有看到优点,因为我不需要多线程。任何建议都会很棒!
谢谢。
答案 0 :(得分:3)
ReadFile无法检测“数据块”是什么。您不应该期望它能够理解您的数据或数据的时间。解决此问题的唯一方法是让您处理它提供的任何内容,使用您自己的数据知识将其划分为“块”以进行进一步处理。如果你得到一个部分块保留它,并在下一次读取时附加到它。
无需为数据调用WaitCommEvent。 ReadFile将等待数据。但是给它一个适当大小的缓冲区,一次要求多个字节。只调用一个字节是非常低效的。选择请求的计数和超时,以便ReadFile将在可接受的时间内返回,无论是否有数据。