串口配置时一些重要且应注意的事项:
除了一般的波特率、数据位、校验位、停止位、超时配置外,还有一些配置也是很重要的,否则有可能出 错丢码或者不正常的现象,在此做一份记录;
本人测试过的正常代码实例:
// 打开串口:
static INT32 Open_Dev(char *dev)
{
INT32 fd;
if((fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY )) == -1) //O_NONBLOCK为非阻塞,经常用到
{
//perror(">can not open the dev!");
return -1;
}
return fd;
}
// 关闭串口:
static void Close_Dev(INT32 fd)
{
if(fd > 0)
{
close(fd);
}
}
// 设置波特率:
static INT32 Set_Baudrate(INT32 fd,UINT32 baudrate)
{
UINT32 speed_arr[] = {B57600,B38400,B19200,B9600,B4800,B2400,B1200,B600,B300,}; //define in termios.h
UINT32 baud_arr[] = {57600,38400,19200,9600,4800,2400,1200,600,300,};
UINT32 i;
UINT32 status;
struct termios opt;
tcgetattr(fd,&opt); //get attr
for(i=0; i<sizeof(baud_arr)/sizeof(UINT32); i++)
{
if(baudrate == baud_arr[i])
{
tcflush(fd,TCIOFLUSH); //flush
cfsetispeed(&opt,speed_arr[i]); //set in baudrate
cfsetospeed(&opt,speed_arr[i]); //set out baudrate
status = tcsetattr(fd,TCSANOW,&opt);
if(status != 0)
{
//perror(">Set_Baudrate: tcseattr failed!/n");
return RET_ERR;
}
tcflush(fd,TCIOFLUSH);
return RET_OK;
}
}
return RET_ERR;
}
// 设置数据位、校验位、停止位和其它重要配置:
static INT32 Set_Parity(INT32 fd,UINT32 databits,UINT32 stopbits,char parity)
{
struct termios opt;
if(tcgetattr(fd,&opt) != 0)
{
//perror(">Set_Parity: tcgetattr failed!/n");
return (RET_ERR);
}
//data bits
opt.c_cflag &= ~CSIZE;
switch (databits)
{
case 5:
opt.c_cflag |= CS5;
break;
case 6:
opt.c_cflag |= CS6;
break;
case 7:
opt.c_cflag |= CS7;
break;
case 8:
opt.c_cflag |= CS8;
break;
default:
//perror(">Unsupported databits/n");
return (RET_ERR);
break;
}
//parity
switch (parity)
{
case 'n':
case 'N':
opt.c_cflag &= ~PARENB; //Clear parity enable
opt.c_iflag &= ~INPCK; // Disnable parity checking
break;
case 'o':
case 'O':
opt.c_cflag |= (PARODD | PARENB);
opt.c_iflag |= INPCK; // Enable parity checking
break;
case 'e':
case 'E':
opt.c_cflag |= PARENB; // Enable parity
opt.c_cflag &= ~PARODD;
opt.c_iflag |= INPCK; // Enable parity checking
break;
case 'S':
case 's': //as no parity
opt.c_cflag &= ~PARENB;
opt.c_cflag &= ~CSTOPB;
break;
default:
//perror(">Unsupported parity/n");
return (RET_ERR);
break;
}
// stop bits
switch (stopbits)
{
case 1:
opt.c_cflag &= ~CSTOPB;
break;
case 2:
opt.c_cflag |= CSTOPB;
break;
default:
//perror(">Unsupported stopbits/n");
return (RET_ERR);
break;
}
tcflush(fd,TCIFLUSH); // Update the options and do it NOW
//time out(here no use because "open(o_NDELAY)")
opt.c_cc[VTIME] = 150; // 15 seconds (1/10sec)
opt.c_cc[VMIN] = 0;
/*---------------------- 重要 ----------------------*/
// 保证本程序不会成为端口的所有者,从而妨碍控制工作和挂起信号 .
opt.c_cflag |= (CLOCAL | CREAD);
// 选择行方式输入 : 行式 输入是不经处理的 .
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 选择行式输出
opt.c_oflag &= ~OPOST;
// 取消软件流控制(不设置可能存在丢码)
opt.c_iflag &= ~(IXON | IXOFF | IXANY);
/*----------------------------------------------------*/
if (tcsetattr(fd,TCSANOW,&opt) != 0)
{
//perror(">Set_Parity: tcsetattr failed!/n");
return (RET_ERR);
}
return (RET_OK);
}
注意上面实例是中的红色字 样(重要的设置);
设置数据位、校验位、停止位和其它重要配置中 的红字部分:因为有些版本的 linux 可能存已默认配置,所以不用配置也可能,但如果默认配置不是这样而又没有进行配置则就可能会出现丢码或者收发码不正常的情况 (本人曾遇到过)!!!