【发布时间】:2012-10-03 04:17:48
【问题描述】:
我正在使用选择调用与使用串行端口 RS232 的外部子系统(已提供相同的协议并作为 Qt 线程实现)进行通信。我们没有用于外部系统的硬件,因此我们使用 .Net 2.0 和 C# 开发了内部模拟器来模拟底层子系统硬件的行为。有 5 个不同的子系统与我们的应用程序通信。子系统的每个接口都实现为 Qt 线程。由于这不是一个实时应用程序,而且当我们使用模拟器进行通信时,我们没有实际的硬件,所以所有系统确实会在 24 小时左右找到,然后通信会上下波动,最终所有通信都会中断,但是当我在不关闭应用程序的情况下重新启动模拟器机器时,一切都会好起来的。为什么会这样?
我的猜测是,由于 .Net/C# 不是实时框架,而且模拟器运行 24 小时后,数据发送速度开始变慢,串行端口堵塞;重新启动会刷新所有内容,因此一切都会恢复正常。这只是一个猜测。如果有人有更好的意见,请分享。请注意,模拟器是由不同的 .Net 团队制作的。
注意:每种协议都有不同的数据速率,1 Hz、5 Hz、10 Hz。
有一个系统即使在模拟器重启后也不会恢复通信。本系统的端口配置为
SetPortConfiguration()
{
tcgetattr(Fd,&mOldtio);
mNewtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CRTSCTS;
mNewtio.c_iflag = 0; //setting the input flag to icrnl causes a blank frame to be displayed after every frame.
mNewtio.c_oflag = 0;
mNewtio.c_lflag =ICANON;
mNewtio.c_cflag &=~PARENB;
mNewtio.c_cflag &= ~CSTOPB;
//mNewtio.c_cflag &= ~HUPCL; //added on 24/3/09
mNewtio.c_cc[VEOL]=0; //setting VEOL to '\r' or '\n' causes a blank frame to be displayed after every frame.
mNewtio.c_cc[VKILL] = 0; /* @ */
mNewtio.c_cc[VSTART] = 0; /* Ctrl-q */
mNewtio.c_cc[VSTOP] = 0; /* Ctrl-s */
mNewtio.c_cc[VMIN]=0;
mNewtio.c_cc[VTIME]=0;
tcflush(Fd, TCIFLUSH);
tcflow(Fd,TCION);
tcsetattr(Fd,TCSANOW,&mNewtio);
}
还有一个复位端口功能:
ResetPort()
{
tcflush(Fd, TCIFLUSH); //flush all data received but not read
tcflow(Fd,TCIOFF); //transmits a STOP character, which stops the terminal device from transmitting data to the system
tcsetattr(Fd, TCSANOW, &mOldtio);//set the old terminal settings
ClosePort(); //close port
OpenPort(mStrPortNo); //open the port specified by port number and in read mode
SetPortConfiguration();
}
如果通信中断,我会调用 ResetPort 函数来关闭并重新打开端口。这解决了所有情况下的问题,除了一个系统说 XYZ。 XYZ 系统以 NMEA 格式发送数据,每个数据包作为以回车、换行组合结尾的数据字符串。
任何想法的家伙可能是什么问题?
【问题讨论】:
-
你需要更清楚;我不清楚接收系统是否连接到同一端口上的所有五个子系统,或者它们是否都有一个专用的串行端口。我会假设后者,因为串行端口是点对点的并且不容易共享,但是在问题中明确说明会很好。
标签: c++ qt serial-port