波特率 9600、奇偶校验 none、数据位 8 和停止位 2 的串行读写。无法与设备通信
Serial read write with Baud rate 9600 , parity none, data bits 8 and stop bits 2. Unable to communicate with device
我正在做的项目需要使用设备设置以十六进制发送命令,如下所示:
波特率:9600,奇偶校验:None,停止位:2,数据位:8 (9600, 8N2).
我已经通过使用 minicom 向设备发送数据进行了验证。我能够看到 CRO 上的数据。但是当我通过 C 代码发送数据并且无法在 CRO 上看到数据并且始终将程序输出为 FFFFF 用于读取功能时。
串口读写源码:
int32_t Read()
{
printf("Entering Read function \n");
int fd;
fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
int j=0;
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS1\n");
exit(1);
}
else
{
printf("Port /dev/ttyS1 opened successfully\n");
}
//---------- Setting the Attributes of the serial port using termios structure ---------
struct termios SerialPortSettings; // Create the structure
tcgetattr(fd, &SerialPortSettings); // Get the current attributes of the Serial port
cfsetispeed(&SerialPortSettings,B9600); // Set Read Speed as 9600
cfsetospeed(&SerialPortSettings,B9600); // Set Write Speed as 9600
SerialPortSettings.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB),So No Parity
SerialPortSettings.c_cflag &= ~PARODD; // added
SerialPortSettings.c_cflag |= CS8; // Set the data bits = 8
SerialPortSettings.c_cflag &= CSTOPB; // CSTOPB = 2 Stop bits
SerialPortSettings.c_cflag &= ~CSIZE; // Clears the mask for setting the data size
SerialPortSettings.c_cflag &= ~CRTSCTS; // No Hardware flow Control
SerialPortSettings.c_cflag |= (CREAD | CLOCAL); // Enable receiver,Ignore Modem Control lines
SerialPortSettings.c_lflag =0; /* RAW input */ // added
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable XON/XOFF flow control both i/p and o/p
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Non Cannonical mode
SerialPortSettings.c_cc[VMIN] = 0; // added for testing // added 1 sec
SerialPortSettings.c_cc[VTIME] = 5; // added for testing // added
SerialPortSettings.c_iflag = 0; /* SW flow control off, no parity checks etc */ // added
SerialPortSettings.c_oflag &= ~OPOST;// No Output Processing
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure
printf("\n ERROR ! in Setting attributes");
else
printf("\n BaudRate = 9600 \n StopBits = 2 \n Parity = None\n");
//------------------------------- Write data to serial port -----------------------------
unsigned char write_buffer[] = {0x28,0x11,0xDF,0xBC}; // Buffer containing characters to write into port
int bytes_written = 0; // Value for storing the number of bytes written to the port
for(j=0;j<4;j++)
{
bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));// use write() to send data to port
// "fd" - file descriptor pointing to the opened serial port
// "write_buffer" - address of the buffer containing data
// "sizeof(write_buffer)" - No of bytes to write
//
printf("Byte written : %x\n",write_buffer[j]);
printf("\n %d Bytes written to ttyS1", bytes_written);
printf("\n +----------------------------------+\n\n");
}
sleep(2);
//------------------------------- Read data from serial port -----------------------------
tcflush(fd, TCIFLUSH); // Discards old data in the rx buffer
unsigned char read_buffer[40]; // Buffer to store the data received
int bytes_read = 0; // Number of bytes read by the read() system call
int i = 0;
bytes_read = read(fd,&read_buffer,40); // Read the data
printf("\n\n Bytes Rxed -%x", bytes_read); // Print the number of bytes read
printf("\n\n ");
for(i=0;i<bytes_read;i++) //printing only the received characters
printf("%x",(int)(*(unsigned char*)(&read_buffer[i])));
printf("\n +----------------------------------+\n\n\n");
close(fd); // Close the serial port
printf("Exiting Read function \n");
}
输出:
Entering Read function
Port /dev/ttyS1 opened successfully
BaudRate = 9600
StopBits = 2
Parity = None
Byte written : 28
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : 11
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : df
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : bc
-1 Bytes written to ttyS1
+----------------------------------+
Bytes Rxed -ffffffff
+----------------------------------+
Exiting Read function
第 1 步为此调用添加错误检查:
tcgetattr(fd, &SerialPortSettings);
喜欢
if (0 > tcgetattr(fd, &SerialPortSettings))
{
/* log and handle error */
}
然后这里
SerialPortSettings.c_cflag |= CS8;
您设置了数据位。
下面两行你清除它
SerialPortSettings.c_cflag &= ~CSIZE;
反过来做。
还有这个
SerialPortSettings.c_cflag &= CSTOPB;
取消设置。
如果你想使用 2 个停止位通过
设置
SerialPortSettings.c_cflag |= CSTOPB;
而不只是做
SerialPortSettings.c_oflag &= ~OPOST;
做
SerialPortSettings.c_oflag = 0;
代码错误地调用了 write()
。这个
for(j=0;j<4;j++)
{
bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));
应该
for(j=0;j<4;j++)
{
bytes_written = write(fd, &write_buffer[j], 1)
或者只是放弃循环然后做
bytes_written = write(fd, write_buffer, sizeof write_buffer);
对read()
的调用也是错误的。
应该是
bytes_read = read(fd, read_buffer, ...
对于 write
和 read
的一些错误,编译器应该警告您。
另请注意 read()
和 write()
return ssize_t
而不是 int
.
最后,我怀疑在读取之前刷新输入缓冲区 (tcflush(fd, TCIFLUSH);
) 是否有意义。
我正在做的项目需要使用设备设置以十六进制发送命令,如下所示: 波特率:9600,奇偶校验:None,停止位:2,数据位:8 (9600, 8N2).
我已经通过使用 minicom 向设备发送数据进行了验证。我能够看到 CRO 上的数据。但是当我通过 C 代码发送数据并且无法在 CRO 上看到数据并且始终将程序输出为 FFFFF 用于读取功能时。
串口读写源码:
int32_t Read()
{
printf("Entering Read function \n");
int fd;
fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
int j=0;
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS1\n");
exit(1);
}
else
{
printf("Port /dev/ttyS1 opened successfully\n");
}
//---------- Setting the Attributes of the serial port using termios structure ---------
struct termios SerialPortSettings; // Create the structure
tcgetattr(fd, &SerialPortSettings); // Get the current attributes of the Serial port
cfsetispeed(&SerialPortSettings,B9600); // Set Read Speed as 9600
cfsetospeed(&SerialPortSettings,B9600); // Set Write Speed as 9600
SerialPortSettings.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB),So No Parity
SerialPortSettings.c_cflag &= ~PARODD; // added
SerialPortSettings.c_cflag |= CS8; // Set the data bits = 8
SerialPortSettings.c_cflag &= CSTOPB; // CSTOPB = 2 Stop bits
SerialPortSettings.c_cflag &= ~CSIZE; // Clears the mask for setting the data size
SerialPortSettings.c_cflag &= ~CRTSCTS; // No Hardware flow Control
SerialPortSettings.c_cflag |= (CREAD | CLOCAL); // Enable receiver,Ignore Modem Control lines
SerialPortSettings.c_lflag =0; /* RAW input */ // added
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable XON/XOFF flow control both i/p and o/p
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Non Cannonical mode
SerialPortSettings.c_cc[VMIN] = 0; // added for testing // added 1 sec
SerialPortSettings.c_cc[VTIME] = 5; // added for testing // added
SerialPortSettings.c_iflag = 0; /* SW flow control off, no parity checks etc */ // added
SerialPortSettings.c_oflag &= ~OPOST;// No Output Processing
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure
printf("\n ERROR ! in Setting attributes");
else
printf("\n BaudRate = 9600 \n StopBits = 2 \n Parity = None\n");
//------------------------------- Write data to serial port -----------------------------
unsigned char write_buffer[] = {0x28,0x11,0xDF,0xBC}; // Buffer containing characters to write into port
int bytes_written = 0; // Value for storing the number of bytes written to the port
for(j=0;j<4;j++)
{
bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));// use write() to send data to port
// "fd" - file descriptor pointing to the opened serial port
// "write_buffer" - address of the buffer containing data
// "sizeof(write_buffer)" - No of bytes to write
//
printf("Byte written : %x\n",write_buffer[j]);
printf("\n %d Bytes written to ttyS1", bytes_written);
printf("\n +----------------------------------+\n\n");
}
sleep(2);
//------------------------------- Read data from serial port -----------------------------
tcflush(fd, TCIFLUSH); // Discards old data in the rx buffer
unsigned char read_buffer[40]; // Buffer to store the data received
int bytes_read = 0; // Number of bytes read by the read() system call
int i = 0;
bytes_read = read(fd,&read_buffer,40); // Read the data
printf("\n\n Bytes Rxed -%x", bytes_read); // Print the number of bytes read
printf("\n\n ");
for(i=0;i<bytes_read;i++) //printing only the received characters
printf("%x",(int)(*(unsigned char*)(&read_buffer[i])));
printf("\n +----------------------------------+\n\n\n");
close(fd); // Close the serial port
printf("Exiting Read function \n");
}
输出:
Entering Read function
Port /dev/ttyS1 opened successfully
BaudRate = 9600
StopBits = 2
Parity = None
Byte written : 28
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : 11
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : df
-1 Bytes written to ttyS1
+----------------------------------+
Byte written : bc
-1 Bytes written to ttyS1
+----------------------------------+
Bytes Rxed -ffffffff
+----------------------------------+
Exiting Read function
第 1 步为此调用添加错误检查:
tcgetattr(fd, &SerialPortSettings);
喜欢
if (0 > tcgetattr(fd, &SerialPortSettings))
{
/* log and handle error */
}
然后这里
SerialPortSettings.c_cflag |= CS8;
您设置了数据位。
下面两行你清除它
SerialPortSettings.c_cflag &= ~CSIZE;
反过来做。
还有这个
SerialPortSettings.c_cflag &= CSTOPB;
取消设置。
如果你想使用 2 个停止位通过
设置 SerialPortSettings.c_cflag |= CSTOPB;
而不只是做
SerialPortSettings.c_oflag &= ~OPOST;
做
SerialPortSettings.c_oflag = 0;
代码错误地调用了 write()
。这个
for(j=0;j<4;j++)
{
bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));
应该
for(j=0;j<4;j++)
{
bytes_written = write(fd, &write_buffer[j], 1)
或者只是放弃循环然后做
bytes_written = write(fd, write_buffer, sizeof write_buffer);
对read()
的调用也是错误的。
应该是
bytes_read = read(fd, read_buffer, ...
对于 write
和 read
的一些错误,编译器应该警告您。
另请注意 read()
和 write()
return ssize_t
而不是 int
.
最后,我怀疑在读取之前刷新输入缓冲区 (tcflush(fd, TCIFLUSH);
) 是否有意义。