读取USB串行数据时出现问题

问题描述 投票:-1回答:2

我尝试使用此代码从USB适配器(PL2303)读取数据。

我的USB芯片规格为57600,无奇偶校验,1个停止位,8位数据模式

我可以从buf []获得一些波形数据,但我不知道这些数字意味着什么。

3, -1225386821, 0, 0, 1934713408, 6, 400, 520192, 45826, 0, 15971, 0, 2, -1091179996, 3, -1226244648, -1225242284, -1227820936, 524408, 2, 45826, 0, 0, 15971, 33188

这是Hexa还是什么?

如何从中获取有意义的数据?我的c ++代码有问题吗?

int open_port(void)
{
    int fd;
    fd=open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);

    if(fd==-1)
    {
        fprintf(stderr, "open_port: Unable to open - %s\n", strerror(errno));
    }
    return (fd);
}

此代码用于Linux。

int main()
{
    int mainfd=0,fd;
    //char chout;
    int buf[5000];    
    struct termios options;
    FILE *pFile;
    pFile = fopen("rawdata.txt","w+");

    mainfd=open_port();
    fcntl(mainfd, F_SETFL, FNDELAY);

    tcgetattr(mainfd, &options);
    cfsetispeed(&options, B57600);
    cfsetospeed(&options, B57600);

    options.c_cflag |= (CLOCAL/CREAD);
    options.c_cflag &= PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag &= CS8;
    options.c_cflag &= ~CRTSCTS;

    options.c_cflag &= ~(ICANON | ECHO | ISIG);


    read(mainfd, buf, 5000);

    for(int i=0;i<5000;i++)     
    {
        cout<<buf[i]<<endl;

        fprintf(pFile,"%d\n",buf[i]);

    }    
    return 0;
}
c++ linux serial-port usb
2个回答
1
投票

这是Hexa还是什么?

如果你的意思是十六进制,那么没有。

如何从中获取有意义的数据?

首先,您必须编写程序以匹配接收到的数据(例如,字节与字,文本与二进制),然后您的程序需要跟踪实际接收数据与未初始化内存的对比情况。

我的c ++代码有问题吗?

是的,您的代码存在几个重大问题。

1.您的程序使用非阻塞模式。

    fd=open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);  
    ...
    fcntl(mainfd, F_SETFL, FNDELAY);

open()使用O_NDELAY选项,然后程序通过fcntl()调用冗余地确保非阻塞模式处于活动状态。 非阻塞模式可以是执行I / O的有效方法,但是您的程序显然没有实现处理其他复杂性的技术。

在阻塞模式下访问串行终端会更好。 只需将fcntl()调用重新编码为:

    fcntl(mainfd, F_SETFL, 0);

2. termios初始化有错误并且不完整。

以下两个陈述是不明确的termios操作:

options.c_cflag &= PARENB;
options.c_cflag &= CS8;

两个语句都只保留这些属性的现有状态。但是你不知道现有状态是什么,更糟糕的是你不知道结果状态是否是你需要的属性状态。

以下语句是错误的,因为c_cflag结构成员中不存在这些termios属性:

options.c_cflag &= ~(ICANON | ECHO | ISIG);

尝试非规范模式的termios初始化是不完整的。该程序保留了未修改的其他几个属性(例如VMIN和VTIME),因此读取行为可能是不可预测的。

3.从不应用termios设置。

您的程序缺少对tcsetattr()的调用,以便实际应用新的termios设置。

4.永远不会评估read()系统调用的返回码。

来自以下系统调用的返回码将被忽略:

   read(mainfd, buf, 5000);  

因此,您的程序无法检测是否发生了任何错误。 如果读取成功,那么您的程序不知道返回了多少数据(如果有的话)。

该程序正在访问未初始化的内存。

您的程序无条件地处理整数数组的5000个元素的整个数组。 但是,根据read()系统调用的语义,指定了最多5000个字节(而不是数组元素或整数),并且系统调用可能(并且很可能)将返回比该最大值更少的数据。 程序应该只访问实际存储在缓冲区中的字节数(如正读(()返回代码所示),而不是盲目地处理整个数组。

是否应将接收到的数据视为有符号整数而不是无符号字节是值得怀疑的。由于read()不能保证也不可能返回整数个sizeof(int)字节,因此盲目地将接收到的数据作为整数处理可能是不正确的。除了提到“波浪”之外,你忽略了描述这些数据所代表的含义。


0
投票

正如@πάταῥεῖ评论的那样,问题是缓冲区被声明为int

请将int中的int buf [5000];更改为unsigned charuint8_t

© www.soinside.com 2019 - 2024. All rights reserved.