LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1026|回复: 0

关于rs422的串口通信问题

[复制链接]
发表于 2007-6-2 14:49:11 | 显示全部楼层 |阅读模式
在项目开发中,有一个外设是rs232转rs422的接口,这是客户方很早以前购买的,没有文档,只有一个windows的源程序库,看了一下大概流程是这样的:先将串口设置为波特率9600、8个数据位、Mark Parity、1个停止位,发送地址信息,然后再将奇偶校验调整为Space Parity发送请求数据,最后读取返回的数据。可是我在linux下一直未成功,返回的数据总是错误的,下面我帖出我在windows上写的测试程序和linux下的测试程序,希望有做过rs422串口通信开发的兄弟给点建议。(windows测试程序的返回结果是正确的,正确结果应为5个字节,而且每次都相同,linux下有时候不返回数据有时候返回4个字节,而且这个4个字节经常变化)

linux下的测试代码:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <string.h>
  9. int
  10. main(int argc, char **argv)
  11. {
  12.   if (argc != 2) {
  13.     printf("Usage: %s <comdev>\n", argv[0]);
  14.     return -1;
  15.   }
  16.   int fd = open(argv[1], O_RDWR | O_NOCTTY);
  17.   if (fd == -1) {
  18.     printf("Initialize COM device failed.\n");
  19.     return -1;
  20.   }
  21.   struct termios options;
  22.   tcgetattr(fd, &options);
  23.   cfmakeraw(&options);
  24.   options.c_cflag &= ~CSIZE;
  25.   options.c_cflag |= CRTSCTS;
  26.   options.c_cflag |= CMSPAR;
  27.   options.c_cflag |= PARODD;
  28.   options.c_cflag |= PARENB;
  29.   options.c_cflag |= CS8;
  30.   options.c_cflag &= ~CSTOPB;
  31.   options.c_iflag |= IGNPAR | IGNBRK | INPCK;
  32.   options.c_cc[VTIME] = 100;
  33.   options.c_cc[VMIN] = 0;
  34.   cfsetispeed(&options, B9600);
  35.   cfsetospeed(&options, B9600);
  36.   tcflush(fd, TCIOFLUSH);
  37.   tcsetattr(fd, TCSANOW, &options);
  38.   char addr = 0x01;
  39.   if (write(fd, &addr, 1) == -1)
  40.     goto failed;
  41.   usleep(1000);
  42.   options.c_cflag &= ~PARODD;
  43.   tcsetattr(fd, TCSADRAIN, &options);
  44.   usleep(1000);
  45.   unsigned char buf[10];
  46.   memcpy(buf, "\x02\x85\x83\x04", 4);
  47.   if (write(fd, buf, 4) == -1)
  48.     goto failed;
  49.   usleep(1000);
  50.   ssize_t read_n;
  51.   int i;
  52.   read_n = read(fd, buf, sizeof(buf));
  53.   printf("result: %d\n", read_n);
  54.   for (i = 0; i < read_n; ++i)
  55.     printf("%02X ", buf[i]);
  56.   printf("\n");
  57.   close(fd);
  58.   return 0;
  59. failed:
  60.   close(fd);
  61.   return -1;
  62. }
复制代码

windows下的测试代码:
  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. int
  6. main(int argc, char **argv)
  7. {
  8.         HANDLE h_com;
  9.         unsigned char addr = 0x01;
  10.         unsigned char buf[10];
  11.         int i;
  12.         DCB dcb;
  13.         COMMTIMEOUTS timeouts;
  14.         DWORD n;
  15.         if (argc != 2) {
  16.                 printf("%s <comdev>\n", argv[0]);
  17.                 return -1;
  18.         }
  19.         h_com = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
  20.                 0, NULL, OPEN_EXISTING, 0, NULL);
  21.         if (h_com == INVALID_HANDLE_VALUE) {
  22.                 printf("Initialize COM device failed\n");
  23.                 return -1;
  24.         }
  25.         GetCommState(h_com, &dcb);
  26.         dcb.BaudRate = 9600;
  27.         dcb.ByteSize = 8;
  28.         dcb.Parity = MARKPARITY;
  29.         dcb.StopBits = ONESTOPBIT;
  30.         SetCommState(h_com, &dcb);
  31.         GetCommTimeouts(h_com, &timeouts);
  32.         timeouts.ReadTotalTimeoutConstant = 10;
  33.         SetCommTimeouts(h_com, &timeouts);
  34.         WriteFile(h_com, &addr, sizeof(addr), &n, NULL);
  35.         Sleep(1);
  36.         dcb.Parity = SPACEPARITY;
  37.         SetCommState(h_com, &dcb);
  38.         memcpy(buf, "\x02\x85\x83\04", 4);
  39.         WriteFile(h_com, buf, 4, &n, NULL);
  40.         Sleep(1);
  41.         ReadFile(h_com, buf, sizeof(buf), &n, NULL);
  42.         printf("read %d bytes\n", n);
  43.         for (i = 0; i < n; ++i)
  44.                 printf("%02x ", buf[i]);
  45.         printf("\n");
  46.         return 0;
  47. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表