Linux 串行 RS-232,第 8 位始终清除(设置为 0)
Linux Serial RS-232, 8th bit always clear (set to 0)
以下是串行通信端口设置
1.波特率:19200
2.奇偶校验:偶数
3.停止位:1
发射器发送几个字节的数据:0x5A 0xA5 0xAA
接收器是使用 termios 串行 API
在 Linux 上用 C 语言编写的
我能够正确接收第一个字节 0x5A,但字节 0xA5 被接收为 0x25,0xAA 被接收为 0x2A,即每个字节的第 8 位设置为 0...为什么?
以下是用于在接收器应用程序上设置串口设置的 C(操作系统: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
}
}
虽然您的代码遵循按位修改 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 位,没有奇偶校验。具有奇偶校验的八位是一种不寻常的配置。您是否正在尝试模拟接收 9 位字符帧(即 9N1)?
以下是串行通信端口设置
1.波特率:19200
2.奇偶校验:偶数
3.停止位:1
发射器发送几个字节的数据:0x5A 0xA5 0xAA
接收器是使用 termios 串行 API
在 Linux 上用 C 语言编写的
我能够正确接收第一个字节 0x5A,但字节 0xA5 被接收为 0x25,0xAA 被接收为 0x2A,即每个字节的第 8 位设置为 0...为什么?
以下是用于在接收器应用程序上设置串口设置的 C(操作系统: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
}
}
虽然您的代码遵循按位修改 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 位,没有奇偶校验。具有奇偶校验的八位是一种不寻常的配置。您是否正在尝试模拟接收 9 位字符帧(即 9N1)?