#include #include #include #include #include #include #include #include #include #include #define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2) //接收超时 #define TIMEOUT_USEC 0 #include "../include/dyp-a05/uart-ctrl.h" /******************************************* * 波特率转换函数(请确认是否正确) ********************************************/ static int convBaudRate(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; } } /******************************************* * Setup serial attr * fdcom: 串口文件描述符,pportinfo: 待设置的端口信息(请确认) * ********************************************/ int uart_set(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)); bzero(&termios_new, sizeof(termios_new)); cfmakeraw(&termios_new); tcgetattr(fdcom, &termios_old); //get the serial port attributions /*------------设置端口属性----------------*/ //baudrates baudrate = convBaudRate(pportinfo -> baudrate); cfsetispeed(&termios_new, baudrate); //填入串口输入端的波特率 cfsetospeed(&termios_new, baudrate); //填入串口输出端的波特率 termios_new.c_cflag |= CLOCAL; //控制模式,保证程序不会成为端口的占有者 termios_new.c_cflag |= CREAD; //控制模式,使能端口读取输入的数据 // 控制模式,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_oflag &= ~OPOST; //输出模式,原始数据输出 termios_new.c_cc[VMIN] = 1; //控制字符, 所要读取字符的最小数量 termios_new.c_cc[VTIME] = 5; //控制字符, 读取第一个字符的等待时间 unit: (1/10)second tcflush(fdcom, TCIFLUSH); //溢出的数据可以接收,但不读 tmp = tcsetattr(fdcom, TCSANOW, &termios_new); //设置新属性,TCSANOW:所有改变立即生效 tcgetattr(fdcom, &termios_old); return(tmp); } /******************************************* * Open serial port * tty: 端口号 ttyS0, ttyS1, .... * 返回值为串口文件描述符 ********************************************/ int uart_init(const char* dev) { return(open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK)); } /******************************************* * Close serial port ********************************************/ void uart_deinit(int fdcom) { close(fdcom); } /******************************************** * send data * fdcom: 串口描述符,data: 待发送数据,datalen: 数据长度 * 返回实际发送长度 *********************************************/ int uart_txd(int fdcom, const unsigned char *data, int datalen) { int len = 0; len = write(fdcom, data, datalen); if(len == datalen){ return (len); } else{ tcflush(fdcom, TCOFLUSH); return -1; } } /******************************************* * receive data * 返回实际读入的字节数 * ********************************************/ int uart_rxd(int fdcom, unsigned 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){ // tcflush(fdcom, TCIFLUSH); // ms usleep(300000); readlen = read(fdcom, data, datalen); // unsigned char bit = data[0]; return readlen; } else{ return (-1); } // return -1 return (readlen); } #ifdef TEST int fdcom = 0; /** * @brief * @param * @retval */ int main(int argc, char**argv) { fdcom = uart_init("/dev/COM0"); if(fdcom > 0) { PortInfo_t portinfo = {115200, 8, 2, 0, 1, 0}; uart_set(fdcom, &portinfo); printf("[PARAM]: 115200, 8, 2, 0, 1, 0\n"); } else { printf("[ERROR]: open serial port error.\n"); } uart_deinit(fdcom); return 0; } #endif