#include "mycom.h" #define TTY_DEV "/dev/ttyUSB" //端口路径 如果是在电脑端选择ttyUSB,在mini2440端则选择ttySAC //#define TTY_DEV "/dev/ttySAC" #define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)//接收超时 #define TIMEOUT_USEC 0 /************************************************* fuction: char *get_ptty(pportinfo_t pportinfo) description: get thd uart name return: ptty **************************************************/ static char *get_ptty(pportinfo_t pportinfo) { char *ptty=NULL; switch(pportinfo->tty) { case '0': ptty=TTY_DEV"0"; break; case '1': ptty=TTY_DEV"1"; break; case '2': ptty=TTY_DEV"2"; break; } return ptty; } /************************************************* fuction: convbaud(unsigned long int baudrate) description: baud change return: ptty **************************************************/ static int convbaud(unsigned long int baudrate) { switch(baudrate){ case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; default: return B9600; } } /**************************************************************** fuction: convbaud(unsigned long int baudrate) description: set the uart parameters: fdcom: 串口文件描述符, pportinfo: 待设置的串口信息 return: tmp ******************************************************************/ int PortSet(int fdcom, const pportinfo_t pportinfo) { struct termios termios_old, termios_new; int baudrate, tmp; char databit, stopbit, parity, fctl; bzero(&termios_old, sizeof(termios_old));//置字符串前sizeof个字节为零 bzero(&termios_new, sizeof(termios_new)); cfmakeraw(&termios_new);//设置终端属性 tcgetattr(fdcom, &termios_old);//get the serial port attributions /*------------设置端口属性----------------*/ //baudrates baudrate = convbaud(pportinfo -> baudrate);//得到波特率 cfsetospeed(&termios_new, baudrate);//填入串口输出端的波特率 termios_new.c_cflag |= CLOCAL;//控制模式,保证程序不会成为端口的占有者 // 控制模式,flow control fctl = pportinfo-> fctl; switch(fctl){ case '0':{ termios_new.c_cflag &= ~CRTSCTS;//no flow control }break; case '1':{ termios_new.c_cflag |= CRTSCTS;//hardware flow control }break; case '2':{ termios_new.c_iflag |= IXON | IXOFF |IXANY; //software flow control }break; } //控制模式,data bits termios_new.c_cflag &= ~CSIZE;//控制模式,屏蔽字符大小位 databit = pportinfo -> databit; switch(databit){ case '5': termios_new.c_cflag |= CS5; case '6': termios_new.c_cflag |= CS6; case '7': termios_new.c_cflag |= CS7; default: termios_new.c_cflag |= CS8; } //控制模式 parity check parity = pportinfo -> parity; switch(parity){ case '0':{ termios_new.c_cflag &= ~PARENB;//no parity check }break; case '1':{ termios_new.c_cflag |= PARENB;//odd check termios_new.c_cflag &= ~PARODD; }break; case '2':{ termios_new.c_cflag |= PARENB;//even check termios_new.c_cflag |= PARODD; }break; } //控制模式,stop bits stopbit = pportinfo -> stopbit; if(stopbit == '2'){ termios_new.c_cflag |= CSTOPB;//2 stop bits } else{ termios_new.c_cflag &= ~CSTOPB;//1 stop bits } //other attributions default termios_new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//输入模式,原始数据输入 tcflush(fdcom, TCIFLUSH);//溢出的数据可以接收,但不读 tmp = tcsetattr(fdcom, TCSANOW, &termios_new);//设置新属性,TCSANOW:所有改变立即生效 tcgetattr(fdcom, &termios_old); return(tmp); } /**************************************************************** fuction: PortOpen(pportinfo_t pportinfo) description: open serial port parameters: pportinfo: 待设置的串口信息 return: fdcom:文件描述符 ******************************************************************/ int PortOpen(pportinfo_t pportinfo) { int fdcom; //串口文件描述符 char *ptty; ptty = get_ptty(pportinfo); //fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY); fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK); return (fdcom); } /**************************************************************** fuction: PortClose(int fdcom) description: close serial port parameters: fdcom:文件描述符 return: NONE ******************************************************************/ void PortClose(int fdcom) { close(fdcom); } /**************************************************************** fuction: PortSend(int fdcom, char *data, int datalen) description: close serial port parameters: fdcom: 串口描述符,data: 待发送数据,datalen: 数据长度 return: len:实际长度 ******************************************************************/ int PortSend(int fdcom, char *data, int datalen) { int len = 0; len = write(fdcom, data, datalen);//实际写入的长度 if(len == datalen){ return (len); } else{ tcflush(fdcom, TCOFLUSH); return -1; } } /**************************************************************** fuction: PortRecv(int fdcom, char *data, int datalen, int baudrate) description: receive the datas parameters: fdcom:串口描述符, data:接收缓冲区, datalen:接收长度, baudrate:波特率 return: readlen:实际读入的字节数 ******************************************************************/ int PortRecv(int fdcom, char *data, int datalen, int baudrate) { int readlen, fs_sel; fd_set fs_read; struct timeval tv_timeout; FD_ZERO(&fs_read); FD_SET(fdcom, &fs_read); tv_timeout.tv_sec = TIMEOUT_SEC(datalen, baudrate); tv_timeout.tv_usec = TIMEOUT_USEC; fs_sel = select(fdcom+1, &fs_read, NULL, NULL, &tv_timeout); if(fs_sel){ readlen = read(fdcom, data, datalen); return(readlen); } else{ return(-1); } return (readlen); }