C++ 串行端口:来自设备的所有字节的最高有效位均为0

C++ 串行端口:来自设备的所有字节的最高有效位均为0,c++,linux,unix,serial-port,C++,Linux,Unix,Serial Port,伙计们,请告诉我有什么问题-我通过串行端口向设备发送命令(字节序列,包括最高有效位(MSB)=1的字节),设备成功识别命令(因此似乎所有字节都发送正确),并以几乎正确的答案回复。这里的“几乎”表示答案是正确的,只是所有字节的MSB都为零(而其中一些字节的MSB必须为1)。 我在VirtualBox上使用Ubuntu 16,Windows 7作为主机操作系统,在FTDI芯片上使用串行端口作为USB设备。 这里是我的串行端口设置: void com::open() { fd = ::open

伙计们,请告诉我有什么问题-我通过串行端口向设备发送命令(字节序列,包括最高有效位(MSB)=1的字节),设备成功识别命令(因此似乎所有字节都发送正确),并以几乎正确的答案回复。这里的“几乎”表示答案是正确的,只是所有字节的MSB都为零(而其中一些字节的MSB必须为1)。
我在VirtualBox上使用Ubuntu 16,Windows 7作为主机操作系统,在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" );
    }
}
void com::open()
{
fd=:open(“/dev/ttyUSB0”,O|RDWR | O|NOCTTY | O|NDELAY);
如果(fd<0)
{
抛出异常系统(错误“错误打开COM端口”);
}
INTERR;
err=fcntl(fd、F_设置FL、FNDELAY);
如果(错误==-1)
{
close();
抛出异常系统(错误“错误fcntl”);
}
试一试{
set();
}捕获(…){
close();
投掷;
}
}
void com::set()
{
如果(fd==-1)
返回;
结构termios tty;
memset(&tty,0,sizeof(tty));
如果(tcgetattr(fd和tty)!=0)
{
抛出异常系统(ERROR_UNK,“ERROR tcgetattr”);
}
INTERR;
err=cfsetospeed(&tty,B115200);
如果(错误!=0)
{
抛出异常系统(错误“错误fsetospeed”);
}
err=cfsetispeed(&tty,B115200);
如果(错误!=0)
{
抛出异常系统(ERROR_UNK,“ERROR cfsetispeed”);
}
tty.c_cflag&=~CSIZE;
tty.c|u cflag |=CS8;
tty.c|u cflag |=PARENB;
tty.c_cflag&=~PARODD;
tty.c_cflag&=~CSTOPB;
tty.c|u cflag |=CLOCAL;
tty.c|u cflag |=CREAD;
tty.c_cflag&=~CRTSCTS;
tty.c|lflag&=~(ICANON | ECHO | ECHO | ISIG);
tty.c|U iflag |=(INPCK | ISTRIP);
tty.c_iflag和IGNPAR;
tty.c_iflag&=~PARMRK;
tty.c|u iflag&=~(IXON | IXOFF | IXANY);
tty.c_of lag&=~OPOST;
tty.c_cc[VMIN]=0;
tty.c_cc[VTIME]=0;
如果(tcsetattr(fd、TCSANOW和tty)!=0)
{
抛出异常系统(ERROR_UNK,“ERROR tcsettr”);
}
}

编辑我刚刚看到了这个问题。你接到电话了

tty.c_iflag |= (INPCK | ISTRIP);
ISTRIP
表示“去掉第八位”。你需要

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
相比,code>8E1不是很常见。我刚刚看到了这个问题。你接到电话了

tty.c_iflag |= (INPCK | ISTRIP);
ISTRIP
表示“去掉第八位”。你需要

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

相比,code>8E1并不常见,当标志字已经为零时,用
&=~
清除所有这些位是徒劳的。不要写无用的代码。或者更好:出于文档的目的,写它,然后注释掉!这表明您知道所需的确切设置,但却没有让编译器发出额外的代码。@EJP在
tcgetattr
之后不确定它们是否为零,当标志字已经为零时,用
&=~
清除所有这些位是徒劳的。不要写无用的代码。或者更好:出于文档的目的,写它,然后注释掉!这表明您知道所需的确切设置,但没有让编译器发出额外的代码。@EJP不确定这些设置在
tcgetattr
之后是否为零-我遵循设备手册。它说它使用“数据长度:8bit+1奇偶校验;1停止位;字符代码:ASCII 8位代码;垂直(偶数)奇偶校验”。在这种情况下,您不应该在
c\u iflag
上使用
ISTRIP
。看我上面的编辑,没错。谢谢我认为ISTRIP会按照我找到的一些网页上的说明剥离奇偶校验位。对于这些设置,我遵循设备手册。它说它使用“数据长度:8bit+1奇偶校验;1停止位;字符代码:ASCII 8位代码;垂直(偶数)奇偶校验”。在这种情况下,您不应该在
c\u iflag
上使用
ISTRIP
。看我上面的编辑,没错。谢谢我想我找到的一些网页上说的是ISTRIP剥离奇偶校验位。