【发布时间】:2016-12-19 14:13:41
【问题描述】:
我正在使用用 C 编写的 Linux 串行端口。下面是我的 UART 设置
int fd;
struct termios tty_attributes;
fd = open(comport, O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK );
if(fd < 0)
{
perror("open comport error.\n");
exit(EXIT_FAILURE);
}
else
{
if(tcgetattr(fd, &tty_attributes) == -1)
{
perror("tcgetattr termios function error.\n");
exit(EXIT_FAILURE);
}
tty_attributes.c_lflag = 0;
tty_attributes.c_oflag = 0;
tty_attributes.c_iflag = 0;
tty_attributes.c_cflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
tty_attributes.c_cflag |= CS8;
tty_attributes.c_cflag |= CLOCAL;
tty_attributes.c_cflag &= ~CREAD;
tty_attributes.c_oflag &= ~OPOST;
tty_attributes.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
tty_attributes.c_cc[VMIN] = SIZE_STR_FRAME;
cfsetospeed(&tty_attributes, BAUDRATE); //setting communication speed and other attributes
cfsetispeed(&tty_attributes, BAUDRATE);
tcflush(fd, TCIOFLUSH);
tcsetattr(fd, TCSANOW, &tty_attributes); //change immediately
return fd;
}
}
下面是我阅读框架的代码
char* frame_read(int fd)
{
char *ret = NULL;
int read_ret_val;
struct timeval time_val;
if (fd < 0)
{
printf("Before read over comm channel, channel must be initialize\n");
exit(EXIT_FAILURE);
}
memset(frame, 0, SIZE);
fd_set rfds; //read file discriptors
int return_val;
FD_SET(fd, &rfds);
setReceiveMode(fd, TRUE);
tcflush(fd, TCIFLUSH);
tcflush(fd, TCOFLUSH); //flush previous values
return_val = select((fd) + 1, &rfds, NULL, NULL, &time_val);
if (return_val == -1)
{
perror("select");
exit(EXIT_FAILURE);
}
else if (return_val)
{
usleep(100 * 1000);
read_ret_val = read(fd, frame, SIZE);
if (read_ret_val < 0)
{
perror("read");
exit(EXIT_FAILURE);
}
ret = frame;
//printf("inside else if of read\n");
}
}
我有一个 gps 模块与 UART 连接,当我使用 minicom 检查时,我得到了全帧,但是当我通过 uart 接收(使用此代码)时,我只得到前 16 个字节。 谁能指出我的错误。? 这里波特是 9600 ,帧是 64 字节,大小是 64 字节。,我占用的缓冲区也是 64 字节。如有格式错误请见谅。
我的 main.c 文件
int main(int argc, char *argv[])
{
int i=0,j=0;
char *readb;
unsigned char data[34];
static int fd = -1;
struct struct_base_gps *gps;
int command=0;
char COMM_PORTNAME[13];
strcpy( COMM_PORTNAME, argv[1] );// give the first port number for GPS receiving
if((fd = init_comm_channel(COMM_PORTNAME)) < 0 )
{
exit(EXIT_FAILURE);
printf("port is not opened\n");
}
else
{
printf("port is open for communication:\n");
readb = frame_read(fd);
for (i=0;i<=34;i++)
{
data[i] = *(readb +j);
printf("the data is %x\n",data[i]);
j++;
}
}
close (fd);
}
对于 SIZE 是 #定义尺寸 64 和框架是 字符帧[64];
感谢您的反馈,我已经更新了代码。
还更新了我在终端和程序上获取的框架图片。可能会更清楚。
【问题讨论】:
-
与你的问题无关,但使用前需要清除描述符集
rfds。集合基本上是一个包含数组的结构,如果您不首先在集合上使用FD_ZERO,则该数据将未初始化,因此具有indeterminate 值。time_val同样的问题,必须初始化为你想要的超时时间。 -
至于您的问题,您需要创建一个Minimal, Complete, and Verifiable Example 并展示给我们。包括您如何调用这些函数以及您使用的变量的定义。例如,
frame是什么?SIZE是什么? -
最后,通过串行通信发送的数据是streaming。没有固定的消息边界或数据包。如果你需要,你需要自己实现它。这也意味着对
read的一次调用我没有读取完整的消息(“帧”),或者它可能读取更多 而不是单个消息(如果有多个缓冲)。您需要循环阅读,直到收到至少一条消息,并且能够在单个read调用中处理多条消息(并且最后一条消息可能是部分消息)。
标签: c linux serial-port