如何在Linux上将波特率设置为307200?

cai*_*rol 12 c c++ linux serial-port baud-rate

基本上我使用以下代码来设置串口的波特率:

struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
tcsetattr(fd, TCSANOW, &options);
Run Code Online (Sandbox Code Playgroud)

这非常有效.但是我知道我必须使用波特率为307200的设备进行通信.我该如何设置?cfsetispeed(&options, B307200);不起作用,没有B307200定义.

我尝试使用MOXA Uport 1150(实际上是USB转串口转换器)和英特尔主板的标准串口.我不知道后者的确切类型,setserial只是将其报告为16550A.

cyc*_*130 25

Linux对非标准波特率使用脏方法,称为"波特率别名".基本上,您告诉串行驱动程序以B38400不同方式解释该值.这是由成员中的ASYNC_SPD_CUST标志控制的.serial_structflags

您需要手动计算自定义速度的除数,如下所示:

// configure port to use custom speed instead of 38400
ioctl(port, TIOCGSERIAL, &ss);
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
closestSpeed = ss.baud_base / ss.custom_divisor;

if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
    sprintf(stderr, "Cannot set serial port speed to %d. Closest possible is %d\n", speed, closestSpeed));
}

ioctl(port, TIOCSSERIAL, &ss);

cfsetispeed(&tios, B38400);
cfsetospeed(&tios, B38400);
Run Code Online (Sandbox Code Playgroud)

当然,您需要一个具有合适baud_base和除数设置的串行驱动程序.前面的代码段允许2%的偏差,这对于大多数用途应该是可以的.

并告诉司机B38400再次解释为38400波特:

ioctl(mHandle, TIOCGSERIAL, &ss);
ss.flags &= ~ASYNC_SPD_MASK;
ioctl(mHandle, TIOCSSERIAL, &ss);
Run Code Online (Sandbox Code Playgroud)

需要注意的是:我不确定这种方法是否可以在其他*nix风格之间移植.

  • 我的天啊。那只是……太可怕了,真的。:( 在设计 API 之前,有人完全忘记在早餐麦片上添加抽象概念。 (2认同)
  • @unwind 比你想象的更可怕,因为它的记录很糟糕。我想这就是为什么三年前的这个答案仍然得到投票的原因:) (2认同)

pay*_*yne 0

对该速度的支持取决于系统。如果B307200未定义,则您的系统可能不支持它。

这是 stty.c 的源代码: http://www.koders.com/c/fid35874B30FDEAFEE83FAD9EA9A59F983C08B714D7.aspx

您可以看到所有高速变量都已#ifdef,因为对这些速度的支持因系统而异。