请教一个读串口的问题

char buff[1024];
char *dev = “/dev/ser2”;

fd = open(dev, O_RDWR);

if(fd == FALSE)
{
perror(“CAN NOT OPEN SERIAL PORT”);
return ;

}
else
{
tcflush( fd, TCIOFLUSH );
}



while(1)
{
nread=read(fd, buff,1024);
if(nread>0)
{
printf("\nLength: %d\n", nread);
buff[nread+1] = ‘\0’;
printf("\n%s\n", buff);
}

if(nread<0)
{
printf( “The error generated was %d\n”, nread);
}

nread = 0;
}

close(fd);


这是在QNX4.25下的程序。我第一次运行可以读到串口数据,显示正常。但是 第二次再运行就无法读到数据,重启动也是一样。但是用stty +raw 参数设置后可以读到数据,可是数据是一个字节一个字节读到的,而不是整条消息一起读到。请高人指点一下。

物理上,串口数据是一个bit一个bit传的。软件上,从串口可以读到的最小单位是一个Byte,不知道你的“整条消息”是怎么定义的?

我的整条消息是指发到串口上的完整的字符串。通过read函数我可以一次读出整个字符串,而不是要循环多次才能读完。(另外字符串不是很大也就40多个字节)。我用这个程序在QNX上第一次运行,就一次读出了整个字符串,以后就不行了(退出是用ctrl + c,没有执行到close(fd))。我估计是某个参数的问题,请唐先生指点。

我的意思是说,串口的传输方式是先Buffer你要求传送的数据,然后将它们一个一个送出的。如果送到一半时,又有新的数据传送要求,串口将把它们Buffer到上次未传完的数据后。所以,从串口传递的角度,没有“一条消息”这样的概念。只有连续的一个一个字符。如果你一定要有“一条消息”这样的东西,你必须在你的应用程序层,设置“分隔符”。接收方每收到一个“分隔符”,就代表收到了“一条消息”。

另外,你的问题,我估计是终端模式。终端有RAW和Edit两种运行模式。RAW的意思是每个字符都立即送到终端。而Edit的意思是,收集到“一行”字符才送到终端。“一行”的概念,是有换行符(\n)。你试试每次“发一条消息”的时候都在最后加"\n"看看有没有用。

还有,你的字符是纯ASCII,还是任意8位码?ASCII 1-31里面有些字符对终端有特殊意义的。

我想请教一下,我想用485口来进行通讯,可是在helpview里,我看到devc-ser8250只支持232协议,我还能用我的485端口进行通讯吗?请高手指点。如果可以,是不是电气连接使用485,而协议使用232协议??我不太明白,请大家多帮忙。谢谢。

问题回答:485和232的通讯一样,你只要知道485能多接设备并延长了通讯距离就行了。我的问题求救:我也发现类似的问题就是Open串口后,用write函数写信息,然后刷新缓冲区并关闭串口,可是我明显感觉到接受数据的机器明显滞后,接受数据是工控机,通讯软件是标准的串口测试软件,不知道是什么问题?2就是我想作个串口发送数据空中断函数,不知道怎么做?那位大侠能提高一个例子。多谢

不知道“明显滞后”到底有多慢。通常115200波特率时,速度约在10KBytes/s。而9600波特率只有960Bytes/s。然后还有接收接收后的处理,显示。

可以试试连两台QNX机器,这样可以仔细从每一步观察时间。

不知道什么叫“串口发送数据空中断函数”?

感谢xtang,继续请教:1通讯明显滞后是指和过去两个工控机通讯比较,波特率等都是9600,两个工控机串行通讯时虽然波特率时9600,但是基本上是你发数据,接受数据的机器就接到数据了。而通过qnx系统的write函数写串口后,另外一台工控机接受到数据基本上需要等上3-4秒,而我传输的数据只有2个字节,也就是2*8/960bytes/s=传输所需时间外加显示时间(其实显示是很快的),我感觉是否是我在qnx系统启动里用了.devc-ser8250 -b9600,8,n,1 这里面有隐含的串口数据缓冲区,或是其它的串口数据缓冲区影响了数据的发送,虽然是我用write函数写数据了,但是数据是在某个缓存里面,并没有直接发送出去。2的问题是:用write函数向串口发数据滞后,没办法我只好用out8(com1)函数直接对串口地址进行操作了,但是这个机制要求你查询串口发送数据缓存是否空,否则发送数据会重叠。因此我想发送数据用中断的方式,因为你用查询的方式是需要不断查看串口发送缓冲区是否空,在串行通讯中可对中断寄存器设置是接到串行数据中断还是发送数据空中断,有很多中断相应源设置的 方法,可是我设置了发送数据空中断功能和接到数据中断,可是发送数据空中断始终不来,而接到数据中断却非常正常。多谢大侠,你在加拿大么?我是否可以通过电话和你联系unixtest@163.com

unixtest1: 是不是我只需要用电缆线将两个485端口连接起来就完了,QNX中的串口驱动devc-ser8250有什么特殊的命令行参数设置吗?我不太明白。
请各位高人多多指点,谢谢帮忙。

485连接有单工模式2根线双工模式4根线,记住一端的收接另外一端的发即可。devc-ser8250主要是设置串口通讯速度奇偶校验停止位等详细的可参考这个命令的帮助。

才看见。

write()以后要3-4秒才能收到,确实有问题。可能跟设备的设定有关。试试把它设成"raw"试试。

如果你要自己直接读写端口,记得不要启动(slay)devc-ser8250。否则你的程序会各它一起抢中断,而工作不正常。

感谢唐先生的精辟回答。
想请教一下,在打开串口时是否可以用O_NONBLOCK参数,就是把楼主的open改成:

fd = open(dev, O_RDWR|O_NONBLOCK);
这样以后用串口读写时是不是就是非阻塞的了?
谢谢!

是,不过那样程序就得变成论询的模式,而且“写”串口操作也会变得复杂一点。