Tôi đã viết điều này một thời gian dài trước đây và chỉ cần sao chép và dán các bit cần thiết vào từng dự án.
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int
set_interface_attribs (int fd, int speed, int parity)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
error_message ("error %d from tcgetattr", errno);
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
error_message ("error %d from tcsetattr", errno);
return -1;
}
return 0;
}
void
set_blocking (int fd, int should_block)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
error_message ("error %d from tggetattr", errno);
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
error_message ("error %d setting term attributes", errno);
}
...
char *portname = "/dev/ttyUSB1"
...
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
{
error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
return;
}
set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
set_blocking (fd, 0); // set no blocking
write (fd, "hello!\n", 7); // send 7 character greeting
usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus
// receive 25: approx 100 uS per char transmit
char buf [100];
int n = read (fd, buf, sizeof buf); // read up to 100 characters if ready to read
Các giá trị cho tốc độ được B115200
, B230400
, B9600
, B19200
, B38400
, B57600
, B1200
, B2400
, B4800
vv Các giá trị cho chẵn lẻ là 0
(nghĩa là không chẵn lẻ), PARENB|PARODD
(kích hoạt tính chẵn lẻ và sử dụng lẻ), PARENB
(cho phép tính chẵn lẻ và sử dụng đồng đều), PARENB|PARODD|CMSPAR
(dấu chẵn lẻ) và PARENB|CMSPAR
(khoảng trống không gian).
"Chặn" đặt xem read()
trên cổng có đợi số ký tự được chỉ định đến không. Đặt không chặn có nghĩa là số tiền trả về read()
tuy nhiên nhiều ký tự khả dụng mà không phải chờ thêm, tối đa giới hạn bộ đệm.
Phụ Lục:
CMSPAR
là cần thiết chỉ cho việc lựa chọn nhãn hiệu và không gian chẵn lẻ, mà là không phổ biến. Đối với hầu hết các ứng dụng, nó có thể được bỏ qua. Tệp tiêu đề của tôi /usr/include/bits/termios.h
chỉ cho phép định nghĩa CMSPAR
chỉ khi biểu tượng tiền xử lý __USE_MISC
được xác định. Định nghĩa đó xảy ra (trong features.h
) với
#if defined _BSD_SOURCE || defined _SVID_SOURCE
#define __USE_MISC 1
#endif
Các ý kiến giới thiệu của <features.h>
nói:
/* These are defined by the user (or the compiler)
to specify the desired environment:
...
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things.
...
*/
Bạn đã xem [HOWTO lập trình nối tiếp] (http://tldp.org/HOWTO/Serial-Programming-HOWTO/) chưa? – ribram
EDIT: Tôi sẽ xem liên kết của ribram. Tuy nhiên, điểm vẫn là trong khi thiết bị nối tiếp được biểu diễn dưới dạng tệp, các thiết bị thường có giao diện cụ thể hơn được triển khai thông qua các lệnh gọi hệ thống như 'ioctl' và' fcntl'. –
Tôi đã không nhìn thấy như thế nào, tôi sẽ xem xét! – gnychis