我正在尝试使用 Odroid(单机板)在 C 中读取串口以通过 USB 电缆从 arduino 板获取数据。正在发布传感器数据的是 189。波特率为115200。
读取使用的主要代码:
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/ipc.h>
#include <sys/shm.h>
#include "share.h"
#include <math.h>
#include <stdlib.h>
#pragma GCC diagnostic ignored "-Wwrite-strings"
/*
* @brief Open serial port with the given device name
*
* @return The file descriptor on success or -1 on error.
*/
int open_port(char *port_device)
{
int fd; /* File descriptor for the port */
fd = open(port_device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("open_port: Unable to open /dev/Servo_LIDAR ");
}
else
fcntl(fd, F_SETFL, 0);
return (fd);
}
int main()
{
//--------------------------------------------------------------------------------
struct termios options;
int fd=-1;
char *u_port = "/dev/Servo_LIDAR";
fd=open_port(u_port);
if(fd==-1)
{
printf("port not open");
return -1;
}
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
//Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
//No parity
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//Set the new options for the port...
tcsetattr(fd, TCSANOW, &options);
printf("Reading...\n");
while(true)
{
while(1)
{
//sleep(0.5);
char buff[1024]={0};
char buf[1]={0};
while(1) {
ssize_t res=read(fd, buf, 1);
if(res==0) continue;
buf[res]=0;
strcat(buff,buf);
if (buf[0] == '\n') break;
}
printf("%s\n", buff);
usleep(70000);
break;
}
}
close(fd);
}
我有这样的约会:
187
187187187
188
188188
188188188
188
1888
188
18188
188
186187
187
187
每次应该是 3 个字节的数据,但我遇到了这样的问题。任何建议,谢谢。
最佳答案
您的主要错误涉及语句:
char buf[1]={0};
...
ssize_t res=read(fd, buf, 1);
...
buf[res]=0;
数组 buf[] 被声明为只有 一个 元素长,即 buf[0] 是数组的唯一元素.
read() 系统调用在成功时将返回值 1,因为这是指定的计数。
然后您尝试通过写入 buf[1] 来终止接收到的文本,但那是一个尚未分配的元素。
数组 buf[] 需要至少包含 2 个元素。
此错误的症状会因编译器和主机系统而异。在使用 gcc 4.8.4 的 x86 笔记本电脑上,您的原始程序根本不产生任何输出。
有关终止缓冲区数据的首选方法,请参阅 Linux Serial Read throws Error
代码审查
所有系统调用,包括tc[gs]etattr() 和read(),都应该检查错误返回代码,尤其是当您的程序没有表现如你所愿。
您的termios 配置不完整。您的程序将以任何先前配置的规范或非规范模式执行。这可能会产生意想不到的结果。
一次只读取一个字符(嵌套在多个 while 循环中)效率低下。规范读取可以为每个系统调用返回一行。学习"Two Styles of Input: Canonical or Not"
usleep(70000)
等程序延迟是多余的。文件/设备已打开以阻止读取,因此 read() 在数据可用之前不会返回。
关于c - 串行 c 在 linux 中读取有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36589454/