本人最近在给一个数据采集终端编写一个基于RS485的串口通讯程序,用来给一台保护装置发送指令,并接收该保护装置返回的报文。折腾了一个多星期,得到的结果是指令的发送应该没有问题(我是基于保护装置对我发送的指令有了相应的操作来判断的),但是保护装置回复的报文明显是错的,因为正确的报文应该与我发送给它的指令是一致的。 我用cutecom测试了一下,cutecom是可以正确接收保护装置返回的报文的,所以问题应该出现在我写的程序的读串口数据部分。但我实在不知道怎么弄,特来该论坛求教,积分不多,望大佬不吝赐教。开发平台为ubuntu系统。
下面是我程序收到的报文:
01 06 00 4A 55 2A 16 5B 这个报文是错误的,数据发生了混乱
cutecom收到的报文是:
01 06 00 CA 55 AA 16 DB 这个报文是对的
cutecom的设置为:波特率为9600,数据位为8,奇校验,停止位为1,不用流控制
下面是代码:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include <stdlib.h>
int open_port(int comport)
{
char str[20];
int fd = -1;
if (comport)
{
sprintf(str, "/dev/ttyUSB%d", comport - 1);
fd = open(str, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("Can't Open Serial Port");
return -1;
}
}
return fd;
}
int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio;
bzero(&newtio, sizeof(newtio));
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch (nBits)
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}
switch (nEvent)
{
case 'O':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
}
switch (nSpeed)
{
default:
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
}
if (nStop == 1)
newtio.c_cflag &= ~CSTOPB;
else if (nStop == 2)
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
newtio.c_iflag &= ~(ICRNL | INLCR);
newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
newtio.c_oflag &= ~(ONLCR | OCRNL);
tcflush(fd, TCIOFLUSH);
if (tcsetattr(fd, TCSANOW, &newtio))
{
perror("com set error");
return -1;
}
printf("Serial set done!\n");
return 0;
}
int main(void)
{
int fd, nread, i;
unsigned char buff_send[1024];
char buff_recv[1024];
bzero(buff_send, 1024);
bzero(buff_recv, 1024);
fd_set rd;
if ((fd = open_port(1)) < 0)
{
perror("open_port error");
return -1;
}
if ((i = set_opt(fd, 9600, 8, 'O', 1)) < 0)
{
perror("set_opt error");
return -1;
}
FD_ZERO(&rd);
FD_SET(fd, &rd);
unsigned char data[8] = {0X01, 0X06, 0X00, 0XCA, 0X55, 0XAA, 0X16, 0XDB};
memcpy(buff_send, data, 8);
write(fd, buff_send, 8);
if (select(fd + 1, &rd, NULL, NULL, NULL) < 0)
perror("select");
else
{
while ((nread = read(fd, buff_recv, 1024)) > 0)
{
for (int i = 0; i < nread; i++)
printf("%02X ", buff_recv[i]);
printf("\n");
}
}
close(fd);
return 0;
}
`
我觉得问题要么出在串口的属性设置,要么出在代码的117行开始的收数据段。 恳请大佬赐教!