串行端口:来自设备的字节都有其最高有效位 = 0
serial port: bytes from device all have their most significant bit = 0
请大家告诉我有什么问题-我通过串行端口向设备发送命令(字节序列,包括最高有效位 (MSB) = 1 的字节),设备成功识别命令(所以看起来所有字节发送正确)并回复几乎正确的答案。 "Almost" 这里的意思是答案是正确的,除了所有字节的 MSB 为零(而其中一些必须有 MSB = 1)。
我在 VirtualBox 上使用 Ubuntu 16,Windows 7 作为主机 OS,串口作为 FTDI 芯片上的 USB 设备。
这里是我的串口设置:
void com::open()
{
fd = ::open( "/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY );
if ( fd < 0 )
{
throw exceptionSystem( ERROR_UNK, "Error open COM port" );
}
int err;
err = fcntl(fd, F_SETFL, FNDELAY);
if ( err == -1 )
{
close();
throw exceptionSystem( ERROR_UNK, "Error fcntl" );
}
try{
set();
}catch(...){
close();
throw;
}
}
void com::set()
{
if ( fd == -1 )
return;
struct termios tty;
memset( &tty, 0, sizeof( tty ) );
if ( tcgetattr(fd, &tty) != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error tcgetattr" );
}
int err;
err = cfsetospeed( &tty, B115200 );
if ( err != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error fsetospeed" );
}
err = cfsetispeed( &tty, B115200 );
if ( err != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error cfsetispeed" );
}
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag |= PARENB;
tty.c_cflag &= ~PARODD;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag |= CLOCAL;
tty.c_cflag |= CREAD;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty.c_iflag |= (INPCK | ISTRIP);
tty.c_iflag &= ~IGNPAR;
tty.c_iflag &= ~PARMRK;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_oflag &= ~OPOST;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
if ( tcsetattr( fd, TCSANOW, &tty ) != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error tcsetattr" );
}
}
编辑 我刚刚看到了这个问题。你有这条线
tty.c_iflag |= (INPCK | ISTRIP);
ISTRIP
表示 "strip off the eighth bit"。你需要
tty.c_iflag |= INPCK;
简单地启用输入奇偶校验。
您已启用偶校验
tty.c_cflag |= PARENB;
tty.c_cflag &= ~PARODD;
以及8位字节
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
所以这是一个起始位、8 个数据位、1 个奇偶校验位和 1 个停止位。我不确定 FTDI 芯片是否可以处理所有这些!
如果你不想奇偶校验,使用
tty.c_cflag &= ~PARENB;
如果我诽谤了 FTDI 芯片,我深表歉意 - 在这种情况下,您确定另一端的配置方式相同吗?与 7E1
或 8N1
相比,8E1
不是很常见
请大家告诉我有什么问题-我通过串行端口向设备发送命令(字节序列,包括最高有效位 (MSB) = 1 的字节),设备成功识别命令(所以看起来所有字节发送正确)并回复几乎正确的答案。 "Almost" 这里的意思是答案是正确的,除了所有字节的 MSB 为零(而其中一些必须有 MSB = 1)。
我在 VirtualBox 上使用 Ubuntu 16,Windows 7 作为主机 OS,串口作为 FTDI 芯片上的 USB 设备。
这里是我的串口设置:
void com::open()
{
fd = ::open( "/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY );
if ( fd < 0 )
{
throw exceptionSystem( ERROR_UNK, "Error open COM port" );
}
int err;
err = fcntl(fd, F_SETFL, FNDELAY);
if ( err == -1 )
{
close();
throw exceptionSystem( ERROR_UNK, "Error fcntl" );
}
try{
set();
}catch(...){
close();
throw;
}
}
void com::set()
{
if ( fd == -1 )
return;
struct termios tty;
memset( &tty, 0, sizeof( tty ) );
if ( tcgetattr(fd, &tty) != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error tcgetattr" );
}
int err;
err = cfsetospeed( &tty, B115200 );
if ( err != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error fsetospeed" );
}
err = cfsetispeed( &tty, B115200 );
if ( err != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error cfsetispeed" );
}
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag |= PARENB;
tty.c_cflag &= ~PARODD;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag |= CLOCAL;
tty.c_cflag |= CREAD;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty.c_iflag |= (INPCK | ISTRIP);
tty.c_iflag &= ~IGNPAR;
tty.c_iflag &= ~PARMRK;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_oflag &= ~OPOST;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
if ( tcsetattr( fd, TCSANOW, &tty ) != 0 )
{
throw exceptionSystem( ERROR_UNK, "Error tcsetattr" );
}
}
编辑 我刚刚看到了这个问题。你有这条线
tty.c_iflag |= (INPCK | ISTRIP);
ISTRIP
表示 "strip off the eighth bit"。你需要
tty.c_iflag |= INPCK;
简单地启用输入奇偶校验。
您已启用偶校验
tty.c_cflag |= PARENB;
tty.c_cflag &= ~PARODD;
以及8位字节
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
所以这是一个起始位、8 个数据位、1 个奇偶校验位和 1 个停止位。我不确定 FTDI 芯片是否可以处理所有这些!
如果你不想奇偶校验,使用
tty.c_cflag &= ~PARENB;
如果我诽谤了 FTDI 芯片,我深表歉意 - 在这种情况下,您确定另一端的配置方式相同吗?与 7E1
或 8N1
8E1
不是很常见