CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Linux/Unix社区 >  程序开发区

快要吐血了,一个linux的串口问题,发现接收数据有错误,不知是那里的设置错了。谢谢了啦

楼主flying520520(不老山)2005-04-02 09:37:24 在 Linux/Unix社区 / 程序开发区 提问

我用了下面的方法设置串口,不知是什么原因,接收到的数据会偶有一些不规律的错误,而我在windows下做的串口则很准确.说明硬件设备没有问题,问题出在串口上.  
   
  我的系统是red   hat   linux9.0  
  数据格式:   起始位+8位数据位+1位停止位     奇校验  
   
  波特率:4800b  
   
  都   愁死我了,我检查了好多次,都不知问题出在那,但就是linux有问题,windows下就好好的.同时我用的57600b对另一个设备也没有问题.  
  谢!!!  
   
   
  #include   <termios.h>  
  #include   <stdio.h>  
  #include   <unistd.h>  
  #include   <fcntl.h>  
   
  #include   "iocom.h"  
   
   
  speed_t   syscom_speed(int   speednum)   {   //设定波特率  
        if   (speednum   >=   460800)   return   B460800;  
        if   (speednum   >=   230400)   return   B230400;  
        if   (speednum   >=   115200)   return   B115200;  
        if   (speednum   >=   57600)   return   B57600;  
        if   (speednum   >=   38400)   return   B38400;  
        if   (speednum   >=   19200)   return   B19200;  
        if   (speednum   >=   9600)   return   B9600;  
        if   (speednum   >=   4800)   return   B4800;  
        if   (speednum   >=   2400)   return   B2400;  
        if   (speednum   >=   1800)   return   B1800;  
        if   (speednum   >=   1200)   return   B1200;  
        if   (speednum   >=   600)   return   B600;  
        if   (speednum   >=   300)   return   B300;  
        if   (speednum   >=   200)   return   B200;  
        if   (speednum   >=   150)   return   B150;  
        if   (speednum   >=   134)   return   B134;  
        if   (speednum   >=   110)   return   B110;  
        if   (speednum   >=   75)   return   B75;  
        return   B50;  
  }  
  int   initusbcom(int   _nucom,int   speednum)  
  {  
  struct   termios   pts;  
  char   comnu[12];  
  sprintf(comnu,"/dev/ttyS%d",_nucom);  
   
  int   com;  
  com=open(comnu,   O_RDWR);//打开串口  
  printf("%s\n",comnu);  
  if(com==-1)  
  {  
  printf("error   !open   fail   %d\n",com);  
  }  
  tcgetattr(com,&pts);//取得串口termios  
  pts.c_lflag   &=   ~ICANON;//不启动档准模式  
  pts.c_lflag   &=   ~(ECHO|ECHOCTL|ECHONL);//不回显,不对字接收字符取模,不回显'\n'  
  // pts.c_cflag   |=   HUPCL;  
  pts.c_cc[VMIN]   =   1;  
  pts.c_cc[VTIME]   =0;  
  pts.c_oflag   &=   ~ONLCR;//发送时不改变字符  
  pts.c_cflag   |=   PARENB;//  
  pts.c_cflag   |=   PARODD;//这行和上一行设定校验为奇校验  
  pts.c_cflag   &=~CSTOPB;//一位停止位  
  pts.c_cflag   |=CREAD;//设定接收字符  
  pts.c_iflag   |=IGNPAR;//忽略错误  
  pts.c_iflag   |=INPCK;//进行奇偶校验  
  pts.c_iflag   &=   ~ICRNL;//不改变回车符  
  cfsetospeed(&pts,syscom_speed(speednum));//设定波特率  
  cfsetispeed(&pts,syscom_speed(speednum));  
  tcsetattr(com,TCSANOW,&pts);  
  printf("ok\n");  
  return   com;  
   
  }  
   
  /*  
  main()  
  {  
  int   com;  
  unsigned   char   strread;  
  com=initcom(0,4800);  
  while(1)  
  {  
  read(com,&strread,1);  
  printf("%d\n",strread);  
  }  
   
   
  };  
  */  
  问题点数:0、回复次数:7Top

1 楼gdhyj(gdhyj)回复于 2005-04-02 13:01:31 得分 0

这一段广为流传的串口初始化代码大家都觉得不好使  
  试试这一段  
  tcgetattr(fd,&t);    
  bzero(&t,sizeof(t));    
  fcntl(fd,F_SETFL,0);    
  t.c_cflag   |=   CLOCAL   |   CREAD;    
  t.c_cflag   &=   ~PARENB;    
  t.c_cflag   &=   ~CSTOPB;    
  t.c_cflag   &=   ~CSIZE;    
  t.c_cflag   |=   CS8;    
  t.c_lflag   &=   ~(ICANON   |   ECHO   |   ECHOE   |   ISIG);    
  t.c_oflag   &=   ~OPOST;    
  t.c_cc[VMIN]   =   0;    
  t.c_cc[VTIME]   =   50;Top

2 楼flying520520(不老山)回复于 2005-04-03 21:03:07 得分 0

在等待  
  Top

3 楼yangyouyi(yangyouyi)回复于 2005-04-05 10:27:40 得分 0

linux是真正的分时,可能和这个有关系。你想,设备传动字符的时候并不是要等你读,他才传送。只要开始传送了,它就要一直传送到一个任务完成。可是在设备传送的过程中,你的while循环程序可能没有被分到时间片运行,所以你就丢了字符。你最好用中断的方式来读字符,这样不存在时间片的问题了。Top

4 楼flying520520(不老山)回复于 2005-04-06 13:24:48 得分 0

upTop

5 楼ssli(30岁的程序员)回复于 2005-04-06 13:41:29 得分 0

请参考如下代码,这是我的程序的一部分:  
   
  int   speed_arr[]   =   {B230400,   B115200,   B38400,   B19200,   B9600,   B4800,   B2400,   B1200,   B300,  
          B115200,   B38400,   B19200,   B9600,   B4800,   B2400,   B1200,   B300,   };  
  int   name_arr[]   =   {230400,   115200,   38400,     19200,     9600,     4800,     2400,     1200,     300,  
          115200,   38400,     19200,     9600,   4800,   2400,   1200,     300,   };  
   
  void   set_speed(int   fd,   int   speed)   //set   com   speed  
  {  
      int       i;  
      int       status;  
      struct   termios       Opt;  
      tcgetattr(fd,   &Opt);  
      for   (   i=   0;     i   <   sizeof(speed_arr)   /   sizeof(int);     i++)  
        {  
        if     (speed   ==   name_arr[i])  
        {  
                tcflush(fd,   TCIOFLUSH);  
          cfsetispeed(&Opt,   speed_arr[i]);  
          cfsetospeed(&Opt,   speed_arr[i]);  
          status   =   tcsetattr(fd,   TCSANOW,   &Opt);  
          if     (status   !=   0)  
                          perror("tcsetattr   fd1");  
            return;  
            }  
        tcflush(fd,TCIOFLUSH);  
        }  
  }  
   
  int   set_Parity(int   fd,int   databits,int   stopbits,int   parity)   //set   com   parity   and   other   property  
  {  
  struct   termios   options;  
    if     (   tcgetattr(   fd,&options)     !=     0)  
      {  
      perror("SetupSerial   1");  
      return(FALSE);  
      }  
      options.c_cflag   &=   ~CSIZE;  
      switch   (databits)    
      {  
      case   7:  
      options.c_cflag   |=   CS7;  
      break;  
      case   8:  
  options.c_cflag   |=   CS8;  
  break;  
  default:  
  fprintf(stderr,"Unsupported   data   size\n");  
  return   (FALSE);  
  }  
      switch   (parity)  
      {  
      case   'n':  
  case   'N':  
  options.c_cflag   &=   ~PARENB;       /*   Clear   parity   enable   */  
  options.c_iflag   &=   ~INPCK;           /*   Enable   parity   checking   */  
  break;  
  case   'o':  
  case   'O':  
  options.c_cflag   |=   (PARODD   |   PARENB);      
  options.c_iflag   |=   INPCK;                           /*   Disnable   parity   checking   */  
  break;  
  case   'e':  
  case   'E':  
  options.c_cflag   |=   PARENB;           /*   Enable   parity   */  
  options.c_cflag   &=   ~PARODD;            
  options.c_iflag   |=   INPCK;               /*   Disnable   parity   checking   */  
  break;  
  case   'S':  
  case   's':     /*as   no   parity*/  
  options.c_cflag   &=   ~PARENB;  
  options.c_cflag   &=   ~CSTOPB;  
  break;  
  default:  
  fprintf(stderr,"Unsupported   parity\n");  
  return   (FALSE);  
  }  
             
      switch   (stopbits)  
      {  
      case   1:  
      options.c_cflag   &=   ~CSTOPB;  
  break;  
  case   2:  
  options.c_cflag   |=   CSTOPB;  
  break;  
  default:  
  fprintf(stderr,"Unsupported   stop   bits\n");  
  return   (FALSE);  
  }  
      /*   Set   input   parity   option   */  
   
      if   (parity   !=   'n')  
      options.c_iflag   |=   INPCK;  
  options.c_lflag   =   0;  
  options.c_oflag   =   0;  
  options.c_oflag   |=   OPOST;  
   
  options.c_cflag   |=   CLOCAL   |   CREAD;  
          options.c_cc[VTIME]   =5;   //   15   seconds  
          options.c_cc[VMIN]   =   0;  
   
      tcflush(fd,TCIFLUSH);   /*   Update   the   options   and   do   it   NOW   */  
      if   (tcsetattr(fd,TCSANOW,&options)   !=   0)  
      {  
      perror("SetupSerial   3");  
  return   (FALSE);  
  }  
      return   (TRUE);  
    }  
   
  int   OpenDev(const   char   *Dev)   //Open   com  
  {  
  int fd   =   open(   Dev,   O_RDWR   |   O_NOCTTY);                   //|   O_NOCTTY   |   O_NDELAY  
  if   (-1   ==   fd)  
  {  
  fprintf(stderr,   "Can't   Open   Serial   Port:   %s",   Dev);  
  return   -1;  
  }  
  else  
  return   fd;  
   
  }Top

6 楼flying520520(不老山)回复于 2005-04-07 22:42:06 得分 0

那里有最祥细的LINUX串口资料Top

7 楼flying520520(不老山)回复于 2005-04-10 22:51:55 得分 0

upTop

相关问题

  • linux 串口处理
  • 串口接收数据的问题?
  • 串口接收数据如何处理?
  • 串口数据怎么接收????????
  • 串口接收数据的问题
  • 急!!!!串口通讯接收数据
  • 多串口接收数据问题?
  • 关于串口接收数据(急)
  • 串口接收线程"受扰"超时,影响接收数据的问题?
  • 关于MSComm控件的串口数据接收问题

关键词

  • 数据
  • 字符
  • linux
  • speednum
  • 串口
  • comnu
  • speed
  • 不知
  • 传送
  • 问题

得分解答快速导航

  • 帖主:flying520520

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo