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\n");
return -1;
} else {
fprintf(stderr, "set rawmode ok\n");
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\n");
break;
case -1:
fprintf(stderr, "read fail\n");
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;
}
浙公网安备 33010602011771号