Linux串行RS-232,第8位始终清除(设置为0)

时间:2015-01-03 17:24:41

标签: linux serial-port termios

以下是串行通信端口设置
1. BaudRate:19200
2.平价:偶数 3. StopBits:1

发送器发送几个字节的数据:0x5A 0xA5 0xAA
Receiver使用termios serial API在Linux上用C语言编写 我能够正确接收第一个字节0x5A,但接收字节0xA5为0x25,接收0xAA为0x2A,即每个字节的第8位设置为0 ...为什么?

下面是用于在接收器应用程序上设置串行端口设置的C(OS:Linux)代码提取:

void *threadRecv(void *arg)
{
    char *portName = (char *)arg;
    char ch;
    struct termios portSettings;

    //fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);
    fd = open(portName, O_RDONLY | O_NOCTTY);
    close(fd);
    fd = open(portName, O_RDONLY | O_NOCTTY);
    if(fd == -1)
    {
        printf("Error opening port: %s", portName);
        pthread_exit("Exiting thread");
    }

    cfsetispeed(&portSettings, B19200);

    //Parity
    portSettings.c_cflag &= ~PARENB;
    portSettings.c_cflag |= PARENB;
    portSettings.c_cflag &= ~PARODD;

    //Stop Bit
    portSettings.c_cflag &= ~CSTOPB;

    //Data Size: 8bits
    portSettings.c_cflag &= ~CSIZE;
    portSettings.c_cflag |= CS8;

    portSettings.c_cflag |= CREAD;
    portSettings.c_cflag |= CLOCAL;

    portSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    portSettings.c_iflag |= (INPCK);

    portSettings.c_oflag &= ~OPOST; //For RAW I/P

    portSettings.c_cc[VMIN] = 77;
    portSettings.c_cc[VTIME] = 0;

    if(tcsetattr(fd, TCSANOW, &portSettings) == -1)
    {
        printf("Error setting port: %s", portName);
        pthread_exit("Exiting thread");
    }
    while(1)
    {
        //Recv Logic
    }
}

1 个答案:

答案 0 :(得分:1)

虽然您的代码遵循逐位修改 termios 结构条款的首选做法,但是您的程序通过调用tcgetattr(fd, &portSettings)来忽略结构的显着初始化。
如果未初始化的 termios 结构中的垃圾值启用了iflag.ISTRIP,那么这可以解释您看到的结果。
由于您的代码只对iflag位进行了最小的修改,因此它应该有一个类似于cfmakeraw()所做的声明:

portSettings.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 
                             | INLCR | IGNCR | ICRNL | IXON); 

Serial Programming Guide for POSIX Operating Systems


portSettings.c_cc[VMIN] = 77;
portSettings.c_cc[VTIME] = 0;

如果消息帧同步丢失,则这是一个有问题的配置。只要您有适当的寻线逻辑来重新实现消息同步,指定非零VTIME就是一种允许恢复的安全措施。


BTW raw(也称为非规范)I / O通常为8位,没有奇偶校验。带奇偶校验的8位是一种不寻常的配置。您是否试图模拟接收9位字符帧(即9N1)?