串口发送数据时,发送到一定量后,就发不出去了,请大家看看

xianliti 2009-07-19 06:12:32
系统比较简单:每隔N秒(2秒--5秒)通过串口发一个命令到一块板子上,然后从板子上接收对应的数据。
在XP环境下,用串口调试器运行过好几天,没出什么问题,可以正常收到数据。
在linux下,自己写了一个串口发送和接收数据的程序,刚开始运行正常,过一段时间后程序就在tcdrain()函数处阻塞,过不去了。
串口设置和主要收发数据的代码如下:
串口设置:

44 int fd;
45 struct termios options;
46
47 //open
48 if((fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY))==-1){
49 perror("Unable to open /dev/ttyS0 - ");
50 return -1;
51 }
52 fcntl(fd,F_SETFL,0);
53
54 //config
55 printf("\nconfig port start……\t");
56
57 tcgetattr(fd,&options);
58
59 /*
60 * Set the baud rates to 9600
61 */
62 cfsetispeed(&options,B9600);
63 cfsetospeed(&options,B9600);
64
65 /*
66 * disable RTS and CTS
67 */
68 options.c_cflag &= ~CRTSCTS;
69
70 /*
71 * Enable the receiver and set local mode
72 */
73 options.c_cflag |= (CLOCAL|CREAD);
74
75 /*
76 * Set Character Size,1 stop bit, disable parity bit
77 */
78 options.c_cflag &= ~CSIZE;
79 options.c_cflag |= CS8;
80 options.c_cflag &= ~CSTOPB;
81 options.c_cflag &= ~PARENB;
82
83 /*
84 * Raw input
85 */
86 options.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG|IEXTEN);
87
88 /*
89 * Raw output
90 */
91 options.c_oflag &= ~OPOST;
92
93 /*
94 * 1 byte at a time, no timer
95 */
96 options.c_cc[VMIN] = 0;
97 options.c_cc[VTIME] = 1;
98
99 /*
100 * Set the new options for the port
101 */
102 tcsetattr(fd,TCSANOW,&options);
103
104 printf("done!\n");
105
106
107 return fd;


收发数据的主要代码:

49 while(1){
50 rec_data_index = 0; //每次收到的数据量
51
52 n = write(fd,command,sizeof(command)); //command是一个命令,这里发命令到板子上
53 if(n<0)
54 fputs("write command failed!\n",stderr);
55 else{
56 printf("\nwrite %d bytes!\n",n);
57 send_times++; //debug用
58 }
59
60 if(tcdrain(fd)==-1) //程序运行一段时间后,在这个地方阻塞
61 perror("tcdrain() error - ");
62 else
63 printf("write OK!\n");
64 /*deubg用
65 if(write_delay){
66 write_delay = 0;
67 sleep(1);
68 }
69 */
70 while((n=read(fd,rec_buf,MAX_RECV_BUF))>0){ //开始接收板子发过来的数据
71 for(i=0;i<n;i++)
72 rec_data[rec_data_index++] = rec_buf[i]; //接收到的数据存在rec_data中
73 }
74
75 tcflush(fd,TCIOFLUSH); //一开始没加这行,后来加上这行也还是出错
76
//…… 略去处理数据的代码
102 sleep(2);
103 }




请大家帮忙看看哪里有问题,关键是xp下用串口调试器可以正常跑好几天,说明板子上的程序应该是没问题的。
...全文
1874 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xianliti 2009-07-21
  • 打赏
  • 举报
回复
呵呵。。。程序跑了一天了,问题似乎解决了。问题就出在配置串口上,在配置串口的一开始,把options这个结构体清零,用memset或者bzero都行,加上这一行,问题就解决了。

可是还是不太清楚到底是因为配置中哪个位置位了才会出现问题中描述的那种情况?
aero_boy 2009-07-20
  • 打赏
  • 举报
回复
你发的是什么数据啊,2进度数,还是纯文本啊,
看看这个:
http://www.ibm.com/developerworks/cn/linux/l-serials/index.html
xianliti 2009-07-20
  • 打赏
  • 举报
回复
主要的代码已经在上面贴出来了,第一个是配置串口的代码。第二个是串口收发数据的代码。其他与串口操作无关的代码就不贴了,比较多。

收发的数据都是十六进制的(unsigned char),不是文本
xianliti 2009-07-20
  • 打赏
  • 举报
回复
主要的代码已经在上面贴出来了,第一个是配置串口的代码。第二个是串口收发数据的代码。其他与串口操作无关的代码就不贴了,比较多。

收发的数据都是十六进制的(unsigned char),不是文本
ShowMan 2009-07-19
  • 打赏
  • 举报
回复
这个玩过, 板子因为环境不同是有可能做成数据丢失的。
所以这类传送一般加上CRC校验,如果发错了,可以重新发,
楼主要写成这样的程序才安全。

不过貌似现在的板子不CRC检验安全性也挺高的。
morris88 2009-07-19
  • 打赏
  • 举报
回复
以前做过,不会出现楼主所说的问题。
另外,稳定性、可靠性皆比 windows 更好。
貌似你的程序写的有问题,能否将相关的所有代码贴出来
xianliti 2009-07-19
  • 打赏
  • 举报
回复
搜索了下CSDN里面的帖子,发现以前也有人碰到过我的这个问题,可惜没有看到解决方案。。。
头痛的是XP下串口调试器可正常工作,可是到linux下就不行了,一直认为是自己程序写得有问题。
yhf365 2009-07-19
  • 打赏
  • 举报
回复
PC接收到的数据有误?
板子上的波特率设置可能有偏差,
或者是受电磁干扰过大。
要么就是板子上的串口数据接收程序有bug。

具体是怎么回事,我也看不出来。

楼主自己多调试一下吧。
两边都修改下波特率,
换个RS232接口,
换个串口线等等。

这种问题一般都是只有自己能解决。
慢慢摸索,理论上肯定可以解决的。
xianliti 2009-07-19
  • 打赏
  • 举报
回复
我计算了下,如果是每隔2S发送数据的话,板子上最多就200个字节的数据发到PC上,波特率设的是9600,PC应该是可以在下一次发命令之前收完数据的吧,就算是冲突了,可是我复位开发板,还是阻塞在那不动。
另外,还有一个现象,PC有时收到的数据有错误,并且程序停止之前的一次收到的数据一定有错误。

还有一个情况忘说了,我用了RS232/RS485转换器,PC端接RS232,板子上接RS485,linux是装在虚拟机上的,不知道这些会不会有什么影响,可是XP上串口调试器可以正常运行。
yhf365 2009-07-19
  • 打赏
  • 举报
回复
程序卡在了等待写入结束上。
是不是在写的时候板子也在向PC机发送数据?
我觉得两者冲突的话可能会造成这种情况

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧