当前位置: 技术问答>linux和unix
linux下串口写成功了,但是读始终是失败,read返回是-1,但是同样的操作在windows上就可以。
来源: 互联网 发布时间:2015-10-27
本文导语: 我只是用串口进行数据的通讯,我LINUX下的串口通讯代码如下。 INT32 OpenComPort (INT32 ComPort, INT32 baudrate, INT32 databit, const char *stopbit, char parity) { char *pComPort; ...
我只是用串口进行数据的通讯,我LINUX下的串口通讯代码如下。
INT32 OpenComPort (INT32 ComPort, INT32 baudrate, INT32 databit,
const char *stopbit, char parity)
{
char *pComPort;
INT32 retval;
switch (ComPort) {
case 0:
pComPort = "/dev/ttyS0";
break;
case 1:
pComPort = "/dev/ttyS1";
break;
case 2:
pComPort = "/dev/ttyS2";
break;
case 3:
pComPort = "/dev/ttyS3";
break;
case 4:
pComPort = "/dev/ttyS4";
break;
case 5:
pComPort = "/dev/ttyS5";
break;
case 6:
pComPort = "/dev/ttyS6";
break;
case 7:
pComPort = "/dev/ttyS7";
break;
default:
pComPort = "/dev/ttyS0";
break;
}
fd = open (pComPort, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (-1 == fd) {
fprintf (stderr, "cannot open port %sn", pComPort);
return (-1);
}
tcgetattr (fd, &termios_old); /* save old termios value */
/* 0 on success, -1 on failure */
retval = SetPortAttr (baudrate, databit, stopbit, parity);
if (-1 == retval) {
fprintf (stderr, "nport %s cannot set baudrate at %dn", pComPort,
baudrate);
}
return (retval);
}
/* close serial port by use of file descriptor fd */
void CloseComPort ()
{
/* flush output data before close and restore old attribute */
tcsetattr (fd, TCSADRAIN, &termios_old);
close (fd);
}
INT32 ReadComPort (void *data, INT32 datalength)
{
INT32 retval = 0;
FD_ZERO (&fs_read);
FD_SET (fd, &fs_read);
tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());
tv_timeout.tv_usec = TIMEOUT_USEC;
retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);
if (retval) {
return (read (fd, data, datalength));
}
else
return (-1);
}
/*
* Write datalength bytes in buffer given by UINT8 *data,
* return value: bytes written
* Nonblock mode
*/
INT32 WriteComPort (UINT8 * data, INT32 datalength)
{
INT32 retval, len = 0, total_len = 0;
FD_ZERO (&fs_write);
FD_SET (fd, &fs_write);
tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());
tv_timeout.tv_usec = TIMEOUT_USEC;
for (total_len = 0, len = 0; total_len 0) {
total_len += len;
}
}
else {
tcflush (fd, TCOFLUSH); /* flush all output data */
break;
}
}
return (total_len);
}
/* get serial port baudrate */
static INT32 GetBaudrate ()
{
return (_BAUDRATE (cfgetospeed (&termios_new)));
}
/* set serial port baudrate by use of file descriptor fd */
static void SetBaudrate (INT32 baudrate)
{
termios_new.c_cflag = BAUDRATE (baudrate); /* set baudrate */
}
static void SetDataBit (INT32 databit)
{
termios_new.c_cflag &= ~CSIZE;
switch (databit) {
case 8:
termios_new.c_cflag |= CS8;
break;
case 7:
termios_new.c_cflag |= CS7;
break;
case 6:
termios_new.c_cflag |= CS6;
break;
case 5:
termios_new.c_cflag |= CS5;
break;
default:
termios_new.c_cflag |= CS8;
break;
}
}
static void SetStopBit (const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
else if (0 == strcmp (stopbit, "1.5")) {
termios_new.c_cflag &= ~CSTOPB; /* 1.5 stop bits */
}
else if (0 == strcmp (stopbit, "2")) {
termios_new.c_cflag |= CSTOPB; /* 2 stop bits */
}
else {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
static void SetParityCheck (char parity)
{
switch (parity) {
case 'N': /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
case 'E': /* even */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag &= ~PARODD;
break;
case 'O': /* odd */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag |= ~PARODD;
break;
default: /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
}
}
static INT32 SetPortAttr (INT32 baudrate,
INT32 databit, const char *stopbit, char parity)
{
bzero (&termios_new, sizeof (termios_new));
cfmakeraw (&termios_new);
SetBaudrate (baudrate);
termios_new.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
SetDataBit (databit);
SetParityCheck (parity);
SetStopBit (stopbit);
termios_new.c_oflag & = ~OPOST
termios_new.c_lflag & = ~(ICANON | ECHO | ECHOE | ISIG)
termios_new.c_oflag &= ~OPOST;
termios_new.c_cc[VTIME] = 1; /* unit: 1/10 second. */
termios_new.c_cc[VMIN] = 1; /* minimal characters for reading */
tcflush (fd, TCIFLUSH);
return (tcsetattr (fd, TCSANOW, &termios_new));
}
static INT32 BAUDRATE (INT32 baudrate)
{
switch (baudrate) {
case 0:
return (B0);
case 50:
return (B50);
case 75:
return (B75);
case 110:
return (B110);
case 134:
return (B134);
case 150:
return (B150);
case 200:
return (B200);
case 300:
return (B300);
case 600:
return (B600);
case 1200:
return (B1200);
case 2400:
return (B2400);
case 9600:
return (B9600);
case 19200:
return (B19200);
case 38400:
return (B38400);
case 57600:
return (B57600);
case 115200:
return (B115200);
default:
return (B9600);
}
}
static INT32 _BAUDRATE (INT32 baudrate)
{
/* reverse baudrate */
switch (baudrate) {
case B0:
return (0);
case B50:
return (50);
case B75:
return (75);
case B110:
return (110);
case B134:
return (134);
case B150:
return (150);
case B200:
return (200);
case B300:
return (300);
case B600:
return (600);
case B1200:
return (1200);
case B2400:
return (2400);
case B9600:
return (9600);
case B19200:
return (19200);
case B38400:
return (38400);
case B57600:
return (57600);
case B115200:
return (115200);
default:
return (9600);
}
}
INT32 OpenComPort (INT32 ComPort, INT32 baudrate, INT32 databit,
const char *stopbit, char parity)
{
char *pComPort;
INT32 retval;
switch (ComPort) {
case 0:
pComPort = "/dev/ttyS0";
break;
case 1:
pComPort = "/dev/ttyS1";
break;
case 2:
pComPort = "/dev/ttyS2";
break;
case 3:
pComPort = "/dev/ttyS3";
break;
case 4:
pComPort = "/dev/ttyS4";
break;
case 5:
pComPort = "/dev/ttyS5";
break;
case 6:
pComPort = "/dev/ttyS6";
break;
case 7:
pComPort = "/dev/ttyS7";
break;
default:
pComPort = "/dev/ttyS0";
break;
}
fd = open (pComPort, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (-1 == fd) {
fprintf (stderr, "cannot open port %sn", pComPort);
return (-1);
}
tcgetattr (fd, &termios_old); /* save old termios value */
/* 0 on success, -1 on failure */
retval = SetPortAttr (baudrate, databit, stopbit, parity);
if (-1 == retval) {
fprintf (stderr, "nport %s cannot set baudrate at %dn", pComPort,
baudrate);
}
return (retval);
}
/* close serial port by use of file descriptor fd */
void CloseComPort ()
{
/* flush output data before close and restore old attribute */
tcsetattr (fd, TCSADRAIN, &termios_old);
close (fd);
}
INT32 ReadComPort (void *data, INT32 datalength)
{
INT32 retval = 0;
FD_ZERO (&fs_read);
FD_SET (fd, &fs_read);
tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());
tv_timeout.tv_usec = TIMEOUT_USEC;
retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);
if (retval) {
return (read (fd, data, datalength));
}
else
return (-1);
}
/*
* Write datalength bytes in buffer given by UINT8 *data,
* return value: bytes written
* Nonblock mode
*/
INT32 WriteComPort (UINT8 * data, INT32 datalength)
{
INT32 retval, len = 0, total_len = 0;
FD_ZERO (&fs_write);
FD_SET (fd, &fs_write);
tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());
tv_timeout.tv_usec = TIMEOUT_USEC;
for (total_len = 0, len = 0; total_len 0) {
total_len += len;
}
}
else {
tcflush (fd, TCOFLUSH); /* flush all output data */
break;
}
}
return (total_len);
}
/* get serial port baudrate */
static INT32 GetBaudrate ()
{
return (_BAUDRATE (cfgetospeed (&termios_new)));
}
/* set serial port baudrate by use of file descriptor fd */
static void SetBaudrate (INT32 baudrate)
{
termios_new.c_cflag = BAUDRATE (baudrate); /* set baudrate */
}
static void SetDataBit (INT32 databit)
{
termios_new.c_cflag &= ~CSIZE;
switch (databit) {
case 8:
termios_new.c_cflag |= CS8;
break;
case 7:
termios_new.c_cflag |= CS7;
break;
case 6:
termios_new.c_cflag |= CS6;
break;
case 5:
termios_new.c_cflag |= CS5;
break;
default:
termios_new.c_cflag |= CS8;
break;
}
}
static void SetStopBit (const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
else if (0 == strcmp (stopbit, "1.5")) {
termios_new.c_cflag &= ~CSTOPB; /* 1.5 stop bits */
}
else if (0 == strcmp (stopbit, "2")) {
termios_new.c_cflag |= CSTOPB; /* 2 stop bits */
}
else {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
static void SetParityCheck (char parity)
{
switch (parity) {
case 'N': /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
case 'E': /* even */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag &= ~PARODD;
break;
case 'O': /* odd */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag |= ~PARODD;
break;
default: /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
}
}
static INT32 SetPortAttr (INT32 baudrate,
INT32 databit, const char *stopbit, char parity)
{
bzero (&termios_new, sizeof (termios_new));
cfmakeraw (&termios_new);
SetBaudrate (baudrate);
termios_new.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
SetDataBit (databit);
SetParityCheck (parity);
SetStopBit (stopbit);
termios_new.c_oflag & = ~OPOST
termios_new.c_lflag & = ~(ICANON | ECHO | ECHOE | ISIG)
termios_new.c_oflag &= ~OPOST;
termios_new.c_cc[VTIME] = 1; /* unit: 1/10 second. */
termios_new.c_cc[VMIN] = 1; /* minimal characters for reading */
tcflush (fd, TCIFLUSH);
return (tcsetattr (fd, TCSANOW, &termios_new));
}
static INT32 BAUDRATE (INT32 baudrate)
{
switch (baudrate) {
case 0:
return (B0);
case 50:
return (B50);
case 75:
return (B75);
case 110:
return (B110);
case 134:
return (B134);
case 150:
return (B150);
case 200:
return (B200);
case 300:
return (B300);
case 600:
return (B600);
case 1200:
return (B1200);
case 2400:
return (B2400);
case 9600:
return (B9600);
case 19200:
return (B19200);
case 38400:
return (B38400);
case 57600:
return (B57600);
case 115200:
return (B115200);
default:
return (B9600);
}
}
static INT32 _BAUDRATE (INT32 baudrate)
{
/* reverse baudrate */
switch (baudrate) {
case B0:
return (0);
case B50:
return (50);
case B75:
return (75);
case B110:
return (110);
case B134:
return (134);
case B150:
return (150);
case B200:
return (200);
case B300:
return (300);
case B600:
return (600);
case B1200:
return (1200);
case B2400:
return (2400);
case B9600:
return (9600);
case B19200:
return (19200);
case B38400:
return (38400);
case B57600:
return (57600);
case B115200:
return (115200);
default:
return (9600);
}
}
|
不知道,帮你顶