串口是最常用的设备间通信的接口,本文简单的介绍一下如何使用串口进行通信,文章中使用的代码基本上是参考libmodbus的,有兴趣的可以去看一下源码。
确定使用的串口号:
首先要确定我们要使用的串口是否存在,在shell下可以去dev目录查看该设备驱动是否正常挂载:

我们要使用的是MT7688的2号串口,如上图所示,驱动已经正常挂载,然后可以用linux自带的picocom工具简单的调试一下串口能否使用。

打开指定串口:
入参填入的值:
{
"dev": "/dev/ttyS1",
"speed": 9600,
"parity": "N",
"dataBit": 8,
"stopBit": 1
}
数据结构:
typedef struct
{
char szDev[SENSOR_STR_LEN];
int uiSpeed;
char ucParity;
char ucDataBit;
char ucStopBit;
}SENSOR_CHANNEL_ST;
static int OpenChannell(IN SENSOR_CHANNEL_ST *pstChannel)
{
int fd;
struct termios opt;
speed_t speed;
fd = open(pstChannel->szDev, O_RDWR | O_NOCTTY| O_NDELAY | O_EXCL); //ĬÈÏΪ×èÈû¶Á·½Ê½
if(fd < 0)
{
printf("Get info in modbus Channel error!! szDev=%s, \r\n",pstChannel->szDev);
return -1;
}
tcgetattr(fd, &opt);
memset(&opt, 0, sizeof(struct termios));
switch (pstChannel->uiSpeed)
{
case 9600:
speed = B9600;
break;
case 57600:
speed = B57600;
break;
case 115200:
speed = B115200;
break;
default:
speed = B9600;
}
cfsetispeed(&opt, speed);
cfsetospeed(&opt, speed);
/* C_CFLAG Control options
CLOCAL Local line - do not change "owner" of port
CREAD Enable receiver
*/
opt.c_cflag |= (CREAD | CLOCAL);
opt.c_cflag &= ~CSIZE;
switch (pstChannel->ucDataBit) {
case 5:
opt.c_cflag |= CS5;
break;
case 6:
opt.c_cflag |= CS6;
break;
case 7:
opt.c_cflag |= CS7;
break;
case 8:
default:
opt.c_cflag |= CS8;
break;
}
/* Stop bit (1 or 2) */
if (pstChannel->ucStopBit == 1)
opt.c_cflag &=~ CSTOPB;
else /* 2 */
opt.c_cflag |= CSTOPB;
/* PARENB Enable parity bit
PARODD Use odd parity instead of even */
if (pstChannel->ucParity == 'N') {
/* None */
opt.c_cflag &=~ PARENB;
} else if (pstChannel->ucParity == 'E') {
/* Even */
opt.c_cflag |= PARENB;
opt.c_cflag &=~ PARODD;
} else {
/* Odd */
opt.c_cflag |= PARENB;
opt.c_cflag |= PARODD;
}
if (pstChannel->ucParity == 'N') {
/* None */
opt.c_iflag &= ~INPCK;
} else {
opt.c_iflag |= INPCK;
}
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* Software flow control is disabled */
opt.c_iflag &= ~(IXON | IXOFF | IXANY);
opt.c_oflag &= ~OPOST;
//opt.c_oflag &= ~(ONLCR | OCRNL); //Ìí¼ÓµÄ
//opt.c_iflag &= ~(ICRNL | INLCR);
opt.c_cc[VTIME] = 0;
opt.c_cc[VMIN] = 0;
//tcflush(fd, TCIOFLUSH);
if(tcsetattr(fd, TCSANOW, &opt) != 0)
{
printf("serial error");
close(fd);
return -1;
}
return fd;
}
读写串口:
int main()
{
char uiRevPkt[128]={0};
int fd = -1;
int iLen = 0;
SENSOR_CHANNEL_ST stChannel;
fd = OpenChannell(&stChannel);
if(fd < 0)
{
return -1;
}
while(1)
{
iLen = read(fd, uiRevPkt, sizeof(uiRevPkt));
write(fd, uiRevPkt, iLen);
}
return 0;
}