在使用嵌入式设备的时候,我们常常需要用到串口来传输数据,这些数据通常是二进制数据, 这就要求通讯的时使用正确的配置,下面是我常用的 “API”: /*####################################################################################*//** *# @file: tty.c *# TODO *####################################################################################*/ #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #include <memory.h> #include <string.h> #include <errno.h> #include <sys/time.h> #include <signal.h> #include <sys/select.h> #include <unistd.h> static int ngModem = -1; /** * @method: Open the serial port(strTtyName) and set the attribte * @strTtyName: the tty name (ttyS1 for GPRS modem ttyS0 for com1) * @nBaudRate: the baudrate will be set. * @Return: on success return The device id * : on error: return < 0 */ int TTYOpen(char *strTtyName, int nBaudRate) { int status; struct termios options; if(ngModem > 0) { return(ngModem); } if( (ngModem = open(strTtyName, O_RDWR|O_NONBLOCK) ) == -1) { return(-1); } tcflush(ngModem, TCIOFLUSH); tcgetattr(ngModem, &options); switch(nBaudRate) { case 600: cfsetispeed(&options, B600); cfsetospeed(&options, B600); break; case 1200: cfsetispeed(&options, B1200); cfsetospeed(&options, B1200); break; case 1800: cfsetispeed(&options, B1800); cfsetospeed(&options, B1800); break; case 2400: cfsetispeed(&options, B2400); cfsetospeed(&options, B2400); break; case 4800: cfsetispeed(&options, B4800); cfsetospeed(&options, B4800); break; case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; case 19200: cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; case 38400: cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; case 57600: cfsetispeed(&options, B57600); cfsetospeed(&options, B57600); break; case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; case 230400: cfsetispeed(&options, B230400); cfsetospeed(&options, B230400); break; default: break; } options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; options.c_cflag &= ~CSTOPB; options.c_iflag &= ~IXON; options.c_cc[VTIME] = 3; options.c_cc[VMIN] = 200; options.c_iflag &= ~ICRNL; options.c_iflag &= ~IGNCR; options.c_lflag &= ~ICANON; options.c_cflag |= (CLOCAL | CREAD); options.c_lflag &= ~(ECHO | ECHOE | ISIG); options.c_oflag &= ~OPOST; status = tcsetattr(ngModem, TCSANOW, &options); if(status != 0) { close(ngModem); ngModem = -1; return(-2); } tcflush(ngModem, TCIOFLUSH); return(ngModem); } /** * @method TTYClose TODO * @return TODO */ void TTYClose(void) { if(ngModem < 0) return; close(ngModem); ngModem = -1; } /** * @method: read data from ngModem, the wait time is "timeout"(in seconds) * @strBuf: the buffer to receive the data * @nByte: want read nByte from the device * @nTimeOut: at most wait time * @Return : on success return the read bytes * : on error: return < 0 */ int TTYRead(unsigned char *strBuf, int nByte, int nTimeOut) { int nRead, nRet; int nLeft; fd_set rfds; struct timeval tv; if(ngModem<0) return -1; FD_ZERO(&rfds); FD_SET(ngModem, &rfds); tv.tv_sec = nTimeOut; tv.tv_usec = 0; nLeft = nByte; while(nLeft > 0) { nRet = select(ngModem + 1, &rfds, NULL, NULL, &tv); if(nRet > 0) { nRead = read(ngModem, strBuf, nLeft); if(nRead < 0) { return(nRead); } nLeft -= nRead; strBuf += nRead; } else if(nRet == 0) { if(tv.tv_sec == 0 && tv.tv_usec == 0) { return(nByte - nLeft); } } else { return(-1); } tv.tv_sec = 0; tv.tv_usec = 2000;// 2 ms } return(nByte - nLeft); } /** * @method: Write data to ngModem, the write wait time is "timeout"(in seconds) * @strBuf: the buffer contain the data will be write * @nByte: the data size * @nTimeOut: at most wait time * @Return: on success return the write bytes * : on error: return < 0 */ int TTYWrite(unsigned char *strBuf, int nByte, int nTimeOut) { int nLeft, nRead, nRet; fd_set wfds; struct timeval tv; if(ngModem<0) return -1; FD_ZERO(&wfds); FD_SET(ngModem, &wfds); tv.tv_sec = nTimeOut; tv.tv_usec = 0; nLeft = nByte; while(nLeft > 0) { nRet = select(ngModem + 1, NULL, &wfds, NULL, &tv); if(nRet > 0) { nRead = write(ngModem, strBuf, nLeft); if(nRead <= 0) { return(nByte - nLeft); } nLeft -= nRead; strBuf += nRead; } else if(nRet == 0) { if(tv.tv_sec == 0 && tv.tv_usec == 0) { return(nByte - nLeft); } } else { return(-1); } } return(nByte - nLeft); } /** * @method:flushe data received but not read. */ void TTYClear() { tcflush(ngModem,TCIFLUSH); } 只需要在新项目中添加此.C文件即可调用