无法以某些波特率通信 [英] Can't communicate with certain baud rates

查看:61
本文介绍了无法以某些波特率通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序能够以 4800、9600 和 115200 等波特率进行通信,但不能以 14400 或 38400 进行通信.我必须包含 asm/termios 因为我需要 struct termios2 因为我将使用 c_ispeedc_ospeed 成员来获得任何 buad 速率.

My application is able to communicate with baud rates like 4800, 9600 and 115200 but can't with 14400 or 38400. I have to include asm/termios because I need struct termios2 since I'm going to use c_ispeed and c_ospeed members for any buad rate.

另外我遇到的第二个问题是read函数在VTIME之后没有返回.你知道为什么会这样吗?任何帮助表示赞赏.谢谢.

Also the second problem I encounter is that read function doesn't return afterVTIME. Do you know why this happens? Any help is appreciated. Thanks.

#include <asm/termios.h>

int serialDevice = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);

serialSettings.baudRate = 4800;
serialSettings.dataBits = 8;
serialSettings.hardwareFlowControl = 0;
serialSettings.parity = 0;
serialSettings.parityOdd = 0;
serialSettings.stopBits = 1;
serialSettings.xonxoff = 1;

setSerialSettings(serialDevice, &serialSettings);
//-------------------------------------------------------
int8_t setSerialSettings(int serialDevice, Serial_Params_t *settings)
{
    struct termios2 tty;
    memset(&tty, 0, sizeof tty);

    // get current serial settings
    if (ioctl(serialDevice, TCGETS2, &tty) == -1)
    {
        sendLog("Can't get serial attributes | setSerialSettings", LOG_TYPE_ERROR);
        return FALSE;
    }

    // baudrate
    tty.c_cflag &= ~CBAUD;
    tty.c_cflag |= BOTHER;
    tty.c_ispeed = MAX(110, MIN(settings->baudRate, MAX_BAUDRATE));
    tty.c_ospeed = MAX(110, MIN(settings->baudRate, MAX_BAUDRATE));

    // enable input parity check
    tty.c_iflag |= INPCK;

    // data bits: CS5, CS6, CS7, CS8
    tty.c_cflag &= ~CSIZE;
    switch (settings->dataBits)
    {
    case 5:
        tty.c_cflag |= CS5;
        break;
    case 6:
        tty.c_cflag |= CS6;
        break;
    case 7:
        tty.c_cflag |= CS7;
        break;
    case 8:
    default:
        tty.c_cflag |= CS8;
        break;
    }

    // stop bit
    switch (settings->stopBits)
    {
    case 1:
    default:
        tty.c_cflag &= ~CSTOPB;
        break;
    case 2:
        tty.c_cflag |= CSTOPB;
    }

    // parity
    if (settings->parity == 1)
        tty.c_cflag |= PARENB;
    else
        tty.c_cflag &= ~PARENB;

    // odd/even parity
    if (settings->parityOdd == 1)
        tty.c_cflag |= PARODD;
    else
        tty.c_cflag &= ~PARODD;

    // flow control
    // XON/XOFF
    if (settings->xonxoff == 1)
        tty.c_iflag |= (IXON | IXOFF | IXANY);
    else
        tty.c_iflag &= ~(IXON | IXOFF | IXANY);

    // enable RTS/CTS
    if (settings->hardwareFlowControl == 1)
        tty.c_cflag |= CRTSCTS;
    else
        tty.c_cflag &= ~CRTSCTS;

    tty.c_cc[VMIN] = 1;            // return read function when receive 1 byte
    tty.c_cc[VTIME] = 10;          // 1 seconds read timeout (deciseconds)
    tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines

    // non-canonical mode
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    // flush port & apply attributes
    tcflush(serialDevice, TCIFLUSH);
    if (ioctl(serialDevice, TCSETS2, &tty) == -1)
    {
        sendLog("Can't set serial attributes | setSerialSettings", LOG_TYPE_ERROR);
        return FALSE;
    }
    return TRUE;
}

推荐答案

我的应用程序能够以 4800、9600 和 115200 等波特率进行通信,但不能以 14400 或 38400 进行通信.

My application is able to communicate with baud rates like 4800, 9600 and 115200 but can't with 14400 or 38400.

这里有一篇关于自定义串行速度设置如何工作的非常好的文章:https://github.com/npat-efault/picocom/blob/master/termios2.txt.

There is a pretty nice writeup for how custom serial speed setting works here: https://github.com/npat-efault/picocom/blob/master/termios2.txt.

简而言之,给定由 tty 标识的 struct termios2,要将输入和输出速度设置为自定义值,您必须

In brief, given a struct termios2 identified by tty, to set both input and output speed to custom values, you must

  • 确保 tty.c_cflag &CBAUD == 麻烦.您似乎正确地做到了这一点.
  • tty.c_ospeed 中设置所需的输出速度.你也这样做.
  • 要么

  • ensure that tty.c_cflag & CBAUD == BOTHER. You appear to do this correctly.
  • set the desired output speed in tty.c_ospeed. You do this, too.
  • either

  • 确保 (tty.c_cflag >> IBSHIFT) &CBAUD == B0,此时输出速度也将用作输入速度,
  • 确保 (tty.c_cflag >> IBSHIFT) &CBAUD == BOTHER,在这种情况下 tty.c_ispeed 将用作输入速度.
  • ensure that (tty.c_cflag >> IBSHIFT) & CBAUD == B0, in which case the output speed will also be used as the input speed, or
  • ensure that (tty.c_cflag >> IBSHIFT) & CBAUD == BOTHER, in which case tty.c_ispeed will be used as the input speed.


你不做任何一个.我不确定为什么这会导致某些速度而不是其他速度的错误通信,但据说该驱动程序会玩一些带有速度设置的有趣游戏,也许您已经偶然发现了.


You do not do either of those. I'm uncertain why this would cause incorrect communication for some speeds and not others, but the driver is reputed to play some interesting games with speed settings, and maybe you've stumbled across one.

至于

read 函数在 VTIME

我认为您的期望不正确.您将 VMINVTIME 都设置为非零值.在这种情况下,VTIME 是最大字符间时间,而不是整体读取超时.使用这些设置,阻塞读取将无限期地等待第一个字符,然后将继续读取后续字符,直到请求的数量,只要每个字符到达前一个字符的 VTIME 分秒之内.

I think you have incorrect expectations. You are setting VMIN and VTIME both to nonzero values. In this case, VTIME is the maximum inter-character time, not an overall read timeout. With these settings, a blocking read will wait indefinitely for the first character, then will keep reading subsequent characters, up to the requested number, as long as each one arrives within VTIME deciseconds of the previous one.

如果您希望每次 read() 调用都有一个整体超时,那么将 VMIN 设置为 0,并为某些 read() 做好准备> 调用读取 0 个字节.与往常一样,read() 也可以读取正数但少于请求的字节数.与您目前使用的配置相比,这种配置更可能发生这种情况,具体取决于您选择的 VTIME 和对等方的行为.

If you want an overall timeout on every read() call, then set VMIN to 0, and be prepared for some read() calls to read 0 bytes. As always, read() may also read a positive number of bytes but fewer than requested. That may be more likely to happen in this configuration than in the one you're presently using, depending on your choice of VTIME and the behavior of the peer.

这篇关于无法以某些波特率通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆