LINUX下USB转串口编程中的一点心得
串口设备的名字
普通物理串口是ttySx,比如ttyS0, ttyS1等,USB转串口的设备名为ttyUSBx,比如ttyUSB0, ttyUSB1等
设置读写RAW模式
这一步非常重要,不设置就收不到数据,一个字节都没有,下面是设置RAW模式的代码
int SetRawMode(int fd) { struct termios opt; opt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); opt.c_oflag &= ~OPOST; opt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); opt.c_cflag &= ~(CSIZE|PARENB); opt.c_cflag |= CS8; if (tcsetattr(fd, TCSANOW, &opt)!=0) { fprintf(stderr, "set rawmode fail "); return -1; } else { fprintf(stderr, "set rawmode ok "); return 0; } }
读写超时控制
尤其是读操作,否则经常收不全数据,下面是读的示例代码
int ReadFix(int fd, char* buffer, int FixLen, int Timeout) { struct timeval timeout; fd_set readfds, writefds; int index = 0, rt = 0, s = 0, ms = 0; s = Timeout/1000; ms = Timeout%1000; timeout.tv_sec = s; timeout.tv_usec = ms*1000; FD_ZERO(&readfds); FD_SET(fd, &readfds); switch(select(fd+1, &readfds, NULL, NULL, &timeout)) { case 0: fprintf(stderr, "read timeout "); break; case -1: fprintf(stderr, "read fail "); break; default: if (FD_ISSET(fd, &readfds)) { while (1) { rt = read(fd, buffer+index, FixLen-index); if (rt<=0) { break; } index += rt; if (index >= FixLen) break; } } break; } return index; }
调用流程示例
int main(int argc, char* argv[]) { char szSendBuf[128], szRecvBuf[128]; int rt = 0; OpenSerial(); SetRawMode(); rt = WriteFix(szSendBuf, nSendLen, 5000); rt = ReadFix(szRecvBuf, 20, 5000); if (rt<=0) { // 读失败 return -1; } if (rt<20) { // 未读完,继续读,此处最好循环处理 rt = ReadFix(szRecvBuf+rt, 20-rt, 5000); } CloseSerial(); return 0; }