linux下c++读取串口

目前有两种读取串口的代码实现,分别如下所示,第一种实现起来较为简单,复制下面的代码编译就能使用。第二种方法需要安装依赖项,具体步骤后面详细介绍。
方法一:

#include <errno.h>
#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    /* fetch bytes as they become available */
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

void set_mincount(int fd, int mcount)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error tcgetattr: %s\n", strerror(errno));
        return;
    }

    tty.c_cc[VMIN] = mcount ? 1 : 0;
    tty.c_cc[VTIME] = 5;        /* half second timer */

    if (tcsetattr(fd, TCSANOW, &tty) < 0)
        printf("Error tcsetattr: %s\n", strerror(errno));
}


int main()
{
    char *portname = "/dev/ttyUSB0";
    int fd;
    int wlen;

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    /*baudrate 115200, 8 bits, no parity, 1 stop bit */
    set_interface_attribs(fd, B115200);
    //set_mincount(fd, 0);                /* set to pure timed read */

    /* simple output */
    wlen = write(fd, "Hello!\n", 7);
    if (wlen != 7) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);    /* delay for output */


    /* simple noncanonical input */
    do {
        unsigned char buf[80];
        int rdlen;

        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
            cout<<buf<<endl;
        } else if (rdlen < 0) {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        }
        /* repeat read to get full message */
    } while (1);
}

方法二:
1.在如下github网址中拉去代码。
https://github.com/wjwwood/serial/releases
2.按照如下方法添加更新库

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu quantal main" > /etc/apt/sources.list.d/ros-latest.list'
wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
sudo apt-get update

3.安装依赖项

sudo apt-get install cmake python-catkin-pkg python-empy python-nose python-setuptools libgtest-dev build-essential

4.安装catkin_pkg
登录https://github.com/ros-infrastructure/catkin_pkg/releases下载最新版本,在文件夹下。

sudo make install

5.打开第一步中拉取的代码文件夹

sudo make install

6.简单代码例程
通过串口读取NMEA的GPS协议

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>

#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <regex>
#include <regex.h>
#include <assert.h>
#include "gps2local.h"
#include "serial/serial.h"
#include <fstream>


#include <vector>
#include <boost/algorithm/string.hpp>

using namespace boost;


int fd;//the serial
using namespace std;

void serial_rec(void)     //get serial data and change to xy and 2-5  11-12
{
    /*open the serial and config*/
    serial::Serial my_serial("/dev/ttyUSB0", 115200, serial::Timeout::simpleTimeout(1000));
    cout << "Is the serial port open?";
    if(my_serial.isOpen())
        cout << " Yes." << endl;
    else
        cout << " No." << endl;
    my_serial.flushInput();
    /*open the serial and config*/

    /*log*/
    ofstream serf;
    ofstream findf;
    serf.open("buf.txt");
    findf.open("gga.txt");
    /*log*/

    const int buf_size = 9999;

    /*find gpgga*/
    int iret;
    //char resultfirst[256];
    char* resultfirst;
    /*find gpgga*/

    /**/
    size_t read_size = buf_size;



    int counter = 0;
    int nmatch = 0;
//    string line_info;
    while(1) {
        //puts("Here");
        //printf("Round %d\n", counter);
        string line_info;
        size_t ret = 0;
        try{
            ret = my_serial.readline(line_info, read_size);
        }
        catch(...){
            printf("Something Weird...\n");
            return ;
        }
        if (ret > 10) {
            //strcpy(buf,line_info.c_str());
            //iret = find_first(buf,pattern,resultfirst);
            iret = -1;
            try{
                //iret = find_first(line_info.c_str(), pattern, resultfirst);
                iret = (line_info.substr(0, 6) == "$GPGGA") ? 0: -1;
                if (iret == 0){
                    resultfirst = (char*)line_info.c_str();
                }
            }
            catch(...){
                printf("err1\n");
                return;
            }

            try{
                if(iret == 0) {
                    nmatch++;

                    double lat, lon;
                    int status, nsati;
                    int success = sscanf(resultfirst, 
                                        "$GPGGA,%*f,%lf,N,%lf,E,%d,%d", 
                                        &lat, &lon, &status, &nsati);
                    findf<<"num"<<counter<<endl;
                    findf<<resultfirst<<endl;
                    //cout << counter <<"/" << nmatch <<"\tRead "<< line_info.size()<<": " <<line_info;
                    printf("%d/%d\tRead %d: %s", counter, nmatch, line_info.size(), line_info.c_str());

                    if (success == 4){
                        lat = int(lat/100)+(lat-int(lat/100)*100)/60.0;
                        lon = int(lon/100)+(lon-int(lon/100)*100)/60.0;
                        printf("\tlat=%.8f, lon=%.8f, status=%d, nsati=%d\n", lat, lon, status, nsati);
                    }
                    else{
                        printf("success-%d\n", success);
                    }
                }
                serf<<"num"<<counter<<":"<<line_info.size()<<endl;
                serf<<line_info<<endl;
            }
            catch(...){
                printf("err2 at round %d\n", counter);
                return ;
            }
        }
        counter++;
    }

}


int main()
{
    serial_rec();

    return 0;
}
  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值