Chinaunix

标题: linux下串口通信为什么0x0D总是被传成0x0A? [打印本页]

作者: yybdomain    时间: 2004-08-02 22:34
标题: linux下串口通信为什么0x0D总是被传成0x0A?
两个IMB服务器,运行redhat9,内核为2.4.20,用一根串口线相连,一台发送,另外一台接收后在发送回来,为什么所有的0X0D都被传成0x0a呢?无论用不用奇偶校验,结果都一样。望高手指点。

源码如下:
#include <sys/types.h>;
#include <sys/stat.h>;
#include <stdio.h>;
#include <string.h>;
#include <stdlib.h>;
#include <termios.h>;
#include <unistd.h>;
#include <fcntl.h>;
#include <error.h>;

#define  FALSE   -1
#define  TRUE    0

#define  COM1  "/dev/ttyS0"

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
            B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300,
            38400,  19200,  9600, 4800, 2400, 1200,  300, };

void set_speed(int fd, int 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)
           {
               tcflush(fd, TCIOFLUSH);
            cfsetispeed(&Opt, speed_arr);
            cfsetospeed(&Opt, speed_arr);
            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)
{
        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_cc[VTIME] = 150; // 15 seconds
    options.c_cc[VMIN] = 0;

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

  tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
  if (tcsetattr(fd,TCSANOW,&options) != 0)
          {
                  perror("SetupSerial 3";
                return (FALSE);
        }
  return (TRUE);
}
/**
*@breif 打开串口
*/
int OpenDev(char *Dev)
{
int        fd = open( Dev, O_RDWR);         
        if (-1 == fd)
                {
                        perror("Can't Open Serial Port";
                        return -1;
                }
        else
        return fd;

}

void main(argc,argv)
int argc;
char **argv;
{
   FILE   *fpIn;
   FILE   *fpOut;
   int    fd;
   int    readlen;
   char   pchFileIn[64];
   char   pchFileOut[64];
   char   sendbuf[5000];
   char   rcvbuf[5000];
   int    writelen=0;
   int    cnt;
   
   strcpy(pchFileIn, argv[2]);
   fpIn = fopen(pchFileIn, "rb";
   fd = OpenDev(COM1);
   if (fd>;0)
     set_speed(fd,38400);
   else
    {
       printf("Can't Open Serial Port!\n";
       exit(0);
    }
   if (set_Parity(fd,8,1,'O')== -1)
    {
       printf("Set Parity Error\n";
       exit(1);
    }
   rcvlen=0;
   totallen=0;
   writelen=0;

   while (fread(sendbuf,100,1,fpIn))
    {
       dwErr = write(fd,sendbuf,readlen);        /* send to com1  */
       writelen+=dwErr;
        usleep(1000);         
         
    }
   close(fd);   
   fclose(fpIn);
   exit(0);
}

读代码:
       for(cnt=0;cnt<3000;cnt++)
        {
          dwErr=read(fd,rcvbuf,0x1000);
          if (dwErr<=0)
           {
                   usleep(1000);
                   continue;
           }
          totallen+=dwErr;
         dwErr = fwrite(rcvbuf,dwErr,1,fpOut);
         usleep(1000);
        }
作者: atom    时间: 2004-08-02 22:56
标题: linux下串口通信为什么0x0D总是被传成0x0A?

那么0x0A又被传成什么呢?
fpIn = fopen(pchFileIn, "rb";你的传送文件是不是DOS格式的?
0x0d/0x0a就是回车换行符吧.
作者: yybdomain    时间: 2004-08-03 09:33
标题: linux下串口通信为什么0x0D总是被传成0x0A?
谢谢回帖。  
0x0a还是0x0a。
我的文件是二进制格式,问题是即使不从文件中读,直接在BUFF中赋值0x0d再发送出去,所有的0x0d在接收端都变成了0x0a,我快要疯掉了。

请高手再指点。
作者: q1208c    时间: 2004-08-03 10:27
标题: linux下串口通信为什么0x0D总是被传成0x0A?
这可能是它认为是回车/换行了吧。因为Linux/Unix 下的回车换行是0x0A,所以,它会把0x0D换成0x0A的,另外, IBM 的机器上好象有用EBCD的,那就更不一样了。

你可以试着以bin方式打开文件。
作者: yybdomain    时间: 2004-08-03 20:41
标题: linux下串口通信为什么0x0D总是被传成0x0A?
如果真的是0x0d被解释成回车换行符而换成0x0a的话,那么实际的0x0d值应该怎么传呢?

谢谢。
作者: Poweroff    时间: 2004-08-03 21:31
标题: linux下串口通信为什么0x0D总是被传成0x0A?
俺也觉得是打开文件的问题,和串口通信无关。楼主能不能多贴点有关串口通信的,或者给点资料链接?这一块挺生疏的,但可能会用到
作者: yybdomain    时间: 2004-08-04 11:25
标题: linux下串口通信为什么0x0D总是被传成0x0A?
其实俺也是菜菜的,个人觉得linux下串口就是被当成双工输入输出流而已,使用过程也就是打开、设置波特率等参数,然后就可以进行读写了。

我觉得应该跟打开文件的方式无关,因为即使不用文件的方式,而是直接在内存buff中赋值发送过去也是这样的。
作者: keenor    时间: 2004-10-01 22:16
标题: linux下串口通信为什么0x0D总是被传成0x0A?
man termios
注意:非canon
作者: supeiwang    时间: 2006-01-12 15:03
楼主,解决没?
我也遇到这个问题了,,,呵呵,疯了
作者: csj    时间: 2006-07-29 21:07
标题: 碰巧看到资料
我是初学者,碰巧看到资料,需要的请给我发邮件 wuxipage#hotmail.com




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2