Linux下C语言串口通讯编程示例

 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();
}

参考:

(1)Linux下C语言串口应用编程_linux串口读写程序-CSDN博客

(2)linux查看某串口(或串口终端)的波特率等属性_查看控制台波特率-CSDN博客

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

键盘会跳舞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值