串口是最常用的設備間通信的接口,本文簡單的介紹一下如何使用串口進行通信,文章中使用的代碼基本上是參考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;
}
閱讀更多 soar0603 的文章