免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 21742 | 回复: 10
打印 上一主题 下一主题

linux 串口读取数据被截断,怎样一次全部接收 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-18 15:50 |只看该作者 |倒序浏览
10可用积分
linux 串口读取数据被截断,怎样一次全部接收?
打开串口后,用read读取串口数据,串口发来的
数据为20,而用read读取到的数据却是分多次得到的?
有时只读了8个数据便被截断了,这是为什么??
怎样一次全部接收?? 谢谢

附代码:
  1. #include     <stdio.h>
  2. #include     <unistd.h>     /*Unix标准函数定义*/
  3. #include     <sys/types.h>  /**/
  4. #include     <sys/stat.h>   /**/
  5. #include     <fcntl.h>      /*文件控制定义*/
  6. #include     <termios.h>    /*PPSIX终端控制定义*/
  7. #include     <errno.h>      /*错误号定义*/
  8. #include     <stdlib.h>
  9. #include     <string.h>

  10. int main()
  11. {
  12.         int fd,readnum;
  13.         char *dev="/dev/ttyS0",recv[100];
  14.         struct termios   opt,oldopt;
  15.         
  16.         fd = open( dev, O_RDWR );        
  17.         
  18.         tcgetattr( fd,&oldopt);

  19.         tcgetattr( fd,&opt);
  20.         cfsetispeed(&opt, B9600);//9600
  21.         cfsetospeed(&opt, B9600);

  22.         opt.c_cflag &= ~PARENB; //N
  23.         opt.c_cflag &= ~INPCK;
  24.         opt.c_cflag &= ~CSTOPB;//1
  25.         opt.c_cflag &= ~CSIZE;
  26.         opt.c_cflag |= CS8;    //8

  27.         opt.c_iflag &= ~(IXON | IXOFF | IXANY);

  28.         opt.c_cc[VTIME] = 0;
  29.         opt.c_cc[VMIN] = 0;  

  30.         opt.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
  31.         opt.c_oflag  &= ~OPOST;   /*Output*/

  32.         tcflush(fd, TCIOFLUSH);
  33.         tcsetattr(fd, TCSANOW, &opt);

  34.         while(1)
  35.           {
  36.                 bzero(recv,100);
  37.                    while((readnum = read(fd,recv,100))>0)
  38.                    {
  39.                         printf("%s\n",recv);
  40.                     }
  41.           }
  42.         
  43.         tcflush(fd, TCIOFLUSH);
  44.         tcsetattr(fd, TCSANOW, &oldopt);        
  45.         close(fd);
  46.         printf("exit.");
  47. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2009-12-18 16:27 |只看该作者
char * pbuf = recv;
int remain = 100;
int total = 100;
while(1)
{
     while((remain -= read(fd, pbuf + total - remain ,remain))>0);
     pbuf = recv;
     remain = 100;              
     printf("%s\n",recv);
}

接分..嘿嘿..

也可以用异步接收吧

[ 本帖最后由 readkernel 于 2009-12-18 16:28 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-12-18 16:55 |只看该作者
我想知道截断的原因,如果发来的数据是不定长的,一会20一会30,怎样接收到完整数据
而不会截断
是不是属性设置上哪里不对??

论坛徽章:
0
4 [报告]
发表于 2009-12-18 16:57 |只看该作者

回复 #2 readkernel 的帖子

异步接收是怎样的
能否详细说明一下 谢谢

论坛徽章:
0
5 [报告]
发表于 2009-12-18 17:16 |只看该作者
异步IO操作要描述起来太费篇幅了,google里搜。

http://www.ibm.com/developerworks/cn/linux/l-serials/index.html
这里一篇linux下串口编程基础.

论坛徽章:
0
6 [报告]
发表于 2009-12-19 16:11 |只看该作者

回复 #5 readkernel 的帖子

我写的这段代码也是基于这篇文章的,我只是想知道怎样一次接受全部数据,而不会被截断。
即使是发来的数据是不定长的,也可以全部接收

论坛徽章:
0
7 [报告]
发表于 2010-03-29 12:19 |只看该作者
咱今天也遇到了,顶下

论坛徽章:
0
8 [报告]
发表于 2011-03-13 15:18 |只看该作者
这个要自己设置数据格式,比如你这串数据中包含数据起始标志、数据包长度、校验等。这样实现起来就比较方便。

论坛徽章:
0
9 [报告]
发表于 2011-03-15 21:56 |只看该作者
你可以查一下VTIME和VMIN这两个关键词的含义,网上很多的,至于一次只收8个字节跟串口控制芯片的FIFO大小有关,如16550A串口芯片FIFO大小为16,一般可设置收4,8,16个字节产生一个中断

论坛徽章:
0
10 [报告]
发表于 2011-03-25 08:44 |只看该作者
char *p=recv;
while(1)
          {
                bzero(recv,100);
                   while((readnum = read(fd,p,100))>0)
                   {
                        printf("%s\n",recv);
                        //这里应检查是否读到结束字符, 假定\0是结束符号, 改为
                        //if (p[readnum]=='\0')  p=recv; else p+=readnumber;
                       }
          }
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP