|
在项目开发中,有一个外设是rs232转rs422的接口,这是客户方很早以前购买的,没有文档,只有一个windows的源程序库,看了一下大概流程是这样的:先将串口设置为波特率9600、8个数据位、Mark Parity、1个停止位,发送地址信息,然后再将奇偶校验调整为Space Parity发送请求数据,最后读取返回的数据。可是我在linux下一直未成功,返回的数据总是错误的,下面我帖出我在windows上写的测试程序和linux下的测试程序,希望有做过rs422串口通信开发的兄弟给点建议。(windows测试程序的返回结果是正确的,正确结果应为5个字节,而且每次都相同,linux下有时候不返回数据有时候返回4个字节,而且这个4个字节经常变化)
linux下的测试代码:- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <string.h>
- int
- main(int argc, char **argv)
- {
- if (argc != 2) {
- printf("Usage: %s <comdev>\n", argv[0]);
- return -1;
- }
- int fd = open(argv[1], O_RDWR | O_NOCTTY);
- if (fd == -1) {
- printf("Initialize COM device failed.\n");
- return -1;
- }
- struct termios options;
- tcgetattr(fd, &options);
- cfmakeraw(&options);
- options.c_cflag &= ~CSIZE;
- options.c_cflag |= CRTSCTS;
- options.c_cflag |= CMSPAR;
- options.c_cflag |= PARODD;
- options.c_cflag |= PARENB;
- options.c_cflag |= CS8;
- options.c_cflag &= ~CSTOPB;
- options.c_iflag |= IGNPAR | IGNBRK | INPCK;
- options.c_cc[VTIME] = 100;
- options.c_cc[VMIN] = 0;
- cfsetispeed(&options, B9600);
- cfsetospeed(&options, B9600);
- tcflush(fd, TCIOFLUSH);
- tcsetattr(fd, TCSANOW, &options);
- char addr = 0x01;
- if (write(fd, &addr, 1) == -1)
- goto failed;
- usleep(1000);
- options.c_cflag &= ~PARODD;
- tcsetattr(fd, TCSADRAIN, &options);
- usleep(1000);
- unsigned char buf[10];
- memcpy(buf, "\x02\x85\x83\x04", 4);
- if (write(fd, buf, 4) == -1)
- goto failed;
- usleep(1000);
- ssize_t read_n;
- int i;
- read_n = read(fd, buf, sizeof(buf));
- printf("result: %d\n", read_n);
- for (i = 0; i < read_n; ++i)
- printf("%02X ", buf[i]);
- printf("\n");
- close(fd);
- return 0;
- failed:
- close(fd);
- return -1;
- }
复制代码
windows下的测试代码:- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int
- main(int argc, char **argv)
- {
- HANDLE h_com;
- unsigned char addr = 0x01;
- unsigned char buf[10];
- int i;
- DCB dcb;
- COMMTIMEOUTS timeouts;
- DWORD n;
- if (argc != 2) {
- printf("%s <comdev>\n", argv[0]);
- return -1;
- }
- h_com = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL);
- if (h_com == INVALID_HANDLE_VALUE) {
- printf("Initialize COM device failed\n");
- return -1;
- }
- GetCommState(h_com, &dcb);
- dcb.BaudRate = 9600;
- dcb.ByteSize = 8;
- dcb.Parity = MARKPARITY;
- dcb.StopBits = ONESTOPBIT;
- SetCommState(h_com, &dcb);
- GetCommTimeouts(h_com, &timeouts);
- timeouts.ReadTotalTimeoutConstant = 10;
- SetCommTimeouts(h_com, &timeouts);
- WriteFile(h_com, &addr, sizeof(addr), &n, NULL);
- Sleep(1);
- dcb.Parity = SPACEPARITY;
- SetCommState(h_com, &dcb);
- memcpy(buf, "\x02\x85\x83\04", 4);
- WriteFile(h_com, buf, 4, &n, NULL);
- Sleep(1);
- ReadFile(h_com, buf, sizeof(buf), &n, NULL);
- printf("read %d bytes\n", n);
- for (i = 0; i < n; ++i)
- printf("%02x ", buf[i]);
- printf("\n");
- return 0;
- }
复制代码 |
|