简体   繁体   English

读取USB串行数据时遇到问题

[英]Have a problem with reading USB serial data

I tried to read data from a USB adapter (PL2303) using this code. 我试图使用此代码从USB适配器(PL2303)读取数据。

My USB chip's spec is 57600, No parity, 1 Stop Bits, 8 bit data mode 我的USB芯片的规格是57600,无奇偶校验,1个停止位,8位数据模式

I can get some wave data from buf[], but I don't know what these number means. 我可以从buf []中获取一些wave数据,但是我不知道这些数字是什么意思。

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 3,-1225386821,0,0,1934713408,6,400,520192,45826,0,15971,0,2,2,-1091179996,3,-1226244648,-1225242284,-1227820936,524408,2,45826,0,0 ,15971、33188

Is this Hexa or something? 这是Hexa还是什么?

How do I get meaningful data from this? 如何从中获取有意义的数据? Is there any problem in my c++ code? 我的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);
}

This code is used in Linux. 此代码在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;
}

Is this Hexa or something? 这是Hexa还是什么?

If you mean hexadecimal, then no. 如果是十六进制,则不会。

How do I get meaningful data from this? 如何从中获取有意义的数据?

First you have to write your program to match that data that is received (eg bytes versus words, text versus binary), and then your program needs to keep track of what is actual received data versus uninitialized memory. 首先,您必须编写程序以匹配接收到的数据(例如,字节与字,文本与二进制),然后程序需要跟踪什么是实际接收的数据与未初始化的内存。

Is there any problem in my c++ code? 我的C ++代码有什么问题吗?

Yes, there are several significant problems with your code. 是的,您的代码有几个重大问题。

1. Your program uses nonblocking mode. 1.您的程序使用非阻塞模式。

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

The open() uses the O_NDELAY option, and then the program redundantly ensures that nonblocking mode is active with the fcntl() call. open()使用O_NDELAY选项,然后程序冗余地确保通过fcntl()调用激活非阻塞模式。
Nonblocking mode can be a valid method of performing I/O, but your program clearly does not implement the techniques to handle the additional complexities. 非阻塞模式可以是执行I / O的有效方法,但是您的程序显然不能实现处理其他复杂性的技术。

You would be better off by accessing the serial terminal in blocking mode. 在阻塞模式下访问串行终端会更好。
Simply recode the fcntl() call to: 只需将fcntl()调用重新编码为:

    fcntl(mainfd, F_SETFL, 0);

2. The termios initialization has errors and is incomplete . 2. termios初始化有错误,并且不完整。

The following two statements are ambiguous termios operations: 以下两个语句是模糊的termios操作:

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

Both statements simply preserve the existing state of those attributes. 这两个语句仅保留这些属性的现有状态。 But you don't know what that existing state is, and worse you don't know whether the resulting state will be the attribute state that you require. 但是您不知道现有状态是什么,更糟糕的是,您不知道结果状态是否将是您所需的属性状态。

The following statement is erroneous because those termios attributes do not exist in the c_cflag structure member: 以下语句是错误的,因为这些termios属性在c_cflag结构成员中不存在:

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

The termios initialization that attempts non-canonical mode is incomplete. 尝试非规范模式的termios初始化不完整。 The program leaves several other attributes unmodified (eg VMIN and VTIME), and therefore read behavior can be unpredictable. 该程序使其他几个属性保持不变(例如VMIN和VTIME),因此读取行为可能无法预测。

3. The termios settings are never applied. 3.不会应用termios设置。

Your program is missing a call to tcsetattr() so that the new termios settings are actually applied. 您的程序缺少对tcsetattr()的调用,因此实际上未应用新的termios设置。

4. The return code from the read() syscall is never evaluated. 4.从不评估read()系统调用的返回代码。

The return code from the following syscall is ignored: 来自以下syscall的返回代码将被忽略:

   read(mainfd, buf, 5000);  

As a consequence your program is unable to detect if any error has occurred. 因此,您的程序无法检测是否发生任何错误。
If the read was successful, then your program is unaware how much data was returned (if any). 如果读取成功,则您的程序将不知道返回了多少数据(如果有)。

5. The program is accessing uninitialized memory. 5.程序正在访问未初始化的内存。

Your program unconditionally processes the entire array of 5000 elements of an integer array. 您的程序无条件处理整数数组的5000个元素的整个数组。
However, per the semantics of the read() syscall, a maximum of 5000 bytes (rather than array elements or integers) has been specified, and the syscall may (and most likely will) return even less data than that maximum. 但是,根据read() syscall的语义,已指定最大5000字节(而不是数组元素或整数),并且syscall可能(并且很可能会)返回比该最大值更少的数据。
Instead of blindly processing the entire array, the program should only access the number of bytes (as indicated by a positive read() return code) actually stored in the buffer. 程序不应盲目地处理整个数组,而应仅访问缓冲区中实际存储的字节数(如正的read()返回代码所示)。

Whether the received data should be treated as signed integers rather than as unsigned bytes is questionable. 是否将接收到的数据视为带符号的整数而不是无符号的字节是值得怀疑的。 Since read() is not guaranteed nor likely to return an integral number of sizeof(int) bytes, blindly handling the received data as integers is probably incorrect. 由于不能保证read()也不可能返回整数的sizeof(int)个字节,因此将接收到的数据盲目处理为整数可能是不正确的。 You neglect to describe what this data represents other than a mention of " wave ". 您忽略了此数据所代表的含义,而没有提及“ wave ”。

As @πάτα ῥεῖ commented, the problem is that the buffer is declared int . 正如@πάταῥεῖ所说,问题在于缓冲区被声明为int

Please change the int in int buf [5000]; 请在int buf [5000];更改int int buf [5000]; to unsigned char or uint8_t . unsigned charuint8_t

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM