Linux下一切皆文件,读写串口,与读写普通文件本质上来讲是一致的。对于串口的数据读写,大致仍遵循着以下几个步骤:
(1)打开文件,获取文件描述符
(2)设置串口的波特率,数据位,校验位,停止位以及其它设置(如果遵循使用默认的串口设置,此步骤可以省略)
(3)读/写数据
(4)关闭串口文件描述符
#include <QCoreApplication>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <QString>
#ifdef Q_OS_LINUX
#include <termios.h>
#endif
/**
* @brief set_baudrate 设置波特率
* @param opt
* @param baudrate
*/
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
cfsetispeed(opt, baudrate);
cfsetospeed(opt, baudrate);
}
/**
* @brief set_data_bit 设置数据位
* @param opt
* @param databit
*/
static void set_data_bit (struct termios *opt, unsigned int databit)
{
opt->c_cflag &= ~CSIZE;
switch (databit) {
case 8:
opt->c_cflag |= CS8;
break;
case 7:
opt->c_cflag |= CS7;
break;
case 6:
opt->c_cflag |= CS6;
break;
case 5:
opt->c_cflag |= CS5;
break;
default:
opt->c_cflag |= CS8;
break;
}
}
/**
* @brief set_parity 设置奇偶校验位
* @param opt
* @param parity
*/
static void set_parity (struct termios *opt, char parity)
{
switch (parity) {
case 'N': /* no parity check */
opt->c_cflag &= ~PARENB;
break;
case 'E': /* even */
opt->c_cflag |= PARENB;
opt->c_cflag &= ~PARODD;
break;
case 'O': /* odd */
opt->c_cflag |= PARENB;
opt->c_cflag |= ~PARODD;
break;
default: /* no parity check */
opt->c_cflag &= ~PARENB;
break;
}
}
/**
* @brief set_stopbit 设置停止位
* @param opt
* @param stopbit
*/
static void set_stopbit (struct termios *opt, const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
} else if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
} else if (0 == strcmp (stopbit, "2")) {
opt->c_cflag |= CSTOPB; /* 2 stop bits */
} else {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
/**
* @brief set_port_attr com口属性设置,
* @param fd
* @param baudrate
* @param databit
* @param stopbit
* @param parity
* @param vtime
* @param vmin
* @return
*/
int set_port_attr (
int fd,
int baudrate, // B1200 B2400 B4800 B9600 .. B115200
int databit, // 5, 6, 7, 8
const char *stopbit, // "1", "1.5", "2"
char parity, // N(o), O(dd), E(ven)
int vtime,
int vmin )
{
struct termios opt;
tcgetattr(fd, &opt);
//设置波特率
set_baudrate(&opt, baudrate);
opt.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
//设置数据位
set_data_bit(&opt, databit);
//设置校验位
set_parity(&opt, parity);
//设置停止位
set_stopbit(&opt, stopbit);
//其它设置
opt.c_oflag = 0;
opt.c_lflag |= 0;
opt.c_oflag &= ~OPOST;
opt.c_cc[VTIME] = vtime;
opt.c_cc[VMIN] = vmin;
tcflush (fd, TCIFLUSH);
return (tcsetattr (fd, TCSANOW, &opt));
}
/**
* @brief main
* @param argc
* @param argv
* @return
*/
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int fd;
fd = open("/dev/ttyUSB1",O_RDWR);
if(fd < 0){
perror("open file failed .");
}
set_port_attr(fd,9600,8,"N",'1',0,0);
char buf[128] = {0};
int len = 0;
QString gps_info;
while(1){
memset(buf,0,128);
len = read(fd, buf, sizeof(buf));
printf("length:%d Text:%s\n",len,buf);
// do something here
if(QString(buf).contains("GPGGA")|| QString(buf).contains("GPVTG")
|| QString(buf).contains("GPRMC") || QString(buf).contains("GPGSA"))
{
gps_info += QString(buf);
}
if(QString(buf).contains("GPGSA")){
printf("\033[1m\033[45;33m [Text]:%s \033[0m\n",gps_info.toStdString().c_str());
gps_info.clear(); // 最后一帧
}
usleep(1000*50);
}
close(fd);
return a.exec();
}
参考: