Qt 4.x linux 串口通信(SerialPort)

前言:

之前写过一篇Qt 5.x+串口通信的文章: https://blog.csdn.net/weixin_42837024/article/details/81669540

现在环境变为 qt 4.8 没有Qt 封装的跨平台的 串口类
可以使用网上开源的 posix_qextserialport,qextserialport
我在使用这个库的时候,在linux 正常使用
但是我的环境是 arm 板子 + linux 3.x + qt4.8 交叉编译
用这个库会出现 接收不到数据 (飞凌的板子)
头疼的一批
后来搞了一个库 用着还可以 就一个.h一个.cpp

serialport.h
serialport.cpp

在这里插入图片描述

用起来也很简单,就打开 读写数据

完整代码:

serialport.h

#ifndef SER_COM_PORT_TX_H
#define SER_COM_PORT_TX_H
#include <QSocketNotifier>
#include <linux/fs.h>
#include<fcntl.h>
#include<errno.h>
#include<termio.h>
#include<sys/ioctl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include <stdio.h>
#include<QTimer>
#include<QMutex>
#include<QWidget>

enum BaudRateType
{
    BAUD50,                //POSIX ONLY
    BAUD75,                //POSIX ONLY
    BAUD110,
    BAUD134,               //POSIX ONLY
    BAUD150,               //POSIX ONLY
    BAUD200,               //POSIX ONLY
    BAUD300,
    BAUD600,
    BAUD1200,
    BAUD1800,              //POSIX ONLY
    BAUD2400,
    BAUD4800,
    BAUD9600,
    BAUD14400,             //WINDOWS ONLY
    BAUD19200,
    BAUD38400,
    BAUD56000,             //WINDOWS ONLY
    BAUD57600,
    BAUD76800,             //POSIX ONLY
    BAUD115200,
    BAUD128000,            //WINDOWS ONLY
    BAUD256000             //WINDOWS ONLY
};

enum DataBitsType
{
    DATA_5,
    DATA_6,
    DATA_7,
    DATA_8
};

enum ParityType
{
    PAR_NONE,
    PAR_ODD,
    PAR_EVEN,
    PAR_MARK,               //WINDOWS ONLY
    PAR_SPACE
};

enum StopBitsType
{
    STOP_1,
    STOP_1_5,               //WINDOWS ONLY
    STOP_2
};

enum FlowType
{
    FLOW_OFF,
    FLOW_HARDWARE,
    FLOW_XONXOFF
};


class SerialPort:public QObject
{
    Q_OBJECT

public:
    explicit SerialPort(QWidget *parent = 0);
private:
    int m_fd;
    termios new_serialArry;
    QSocketNotifier *m_notifier;
    QByteArray  *rev_buf;
    QMutex mutex_r;

public :  

    //open
    bool openPort(QString portName,BaudRateType baundRate,DataBitsType dataBits,ParityType parity,
              StopBitsType stopBits, FlowType flow ,int time_out);
    //close
    bool close();

    //write
    int  write(QByteArray buf);

    //read
    QByteArray read();


signals:
    void hasdata();

private slots:
    void remoteDateInComing();





};
#endif // SER_COM_PORT_TX_H

serialport.cpp

#include "serialport.h"
#include<QDebug>
SerialPort::SerialPort(QWidget *parent):
    QObject(parent)
{
    m_fd=-1;
    rev_buf=new QByteArray();
}
//open
bool SerialPort::openPort(QString portName, BaudRateType baundRate, DataBitsType dataBits,
                          ParityType parity, StopBitsType stopBits, FlowType flow, int time_out)
{

    if(m_fd!=-1)
    {
        qDebug("is aready opened!");
        return false;
    }
    rev_buf->clear();
    memset(&new_serialArry,0,sizeof new_serialArry);
    m_fd=::open(portName.toLatin1(),O_RDWR|O_NONBLOCK);
    if( m_fd==-1)
    {
        qDebug("serial port  open erro!");

        return false;
    }

    switch(baundRate)
    {
    case BAUD50:
        new_serialArry.c_cflag |=  B50;
        break;
    case BAUD75:
        new_serialArry.c_cflag |=  B75;
        break;
    case BAUD110:
        new_serialArry.c_cflag |=  B110;
        break;
    case BAUD300:
        new_serialArry.c_cflag |=  B300;
        break;
    case BAUD600:
        new_serialArry.c_cflag |=  B600;
        break;
    case BAUD1200:
        new_serialArry.c_cflag |=  B1200;
        break;
    case BAUD2400:
        new_serialArry.c_cflag |=  B2400;
        break;
    case BAUD4800:
        new_serialArry.c_cflag |=  B4800;
        break;
    case BAUD9600:
        new_serialArry.c_cflag |=  B9600;
        break;
    case BAUD19200:
        new_serialArry.c_cflag |=  B19200;
        break;
    case BAUD38400:
        new_serialArry.c_cflag |=  B38400;
        break;
    case BAUD57600:
        new_serialArry.c_cflag |=  B57600;
        break;
    case BAUD115200:
        new_serialArry.c_cflag |=  B115200;
        break;
    default:
        new_serialArry.c_cflag |=  B9600;
        break;
    }

    switch(dataBits)
    {
    case DATA_5:
        new_serialArry.c_cflag|=CS5;
        break;
    case DATA_6:
        new_serialArry.c_cflag|=CS6;
        break;
    case DATA_7:
        new_serialArry.c_cflag|=CS7;
        break;
    case DATA_8:
        new_serialArry.c_cflag|=CS8;
        break;
    default:
        new_serialArry.c_cflag|=CS8;
        break;
    }

    switch (parity)
    {

    case PAR_NONE:
        new_serialArry.c_cflag &= (~PARENB);
        break;
    case PAR_EVEN:
        new_serialArry.c_cflag &= (~PARODD);
        new_serialArry.c_cflag |= PARENB;
        break;
    case PAR_ODD:
        new_serialArry.c_cflag |= (PARODD|PARENB);
        break;
    default:
        break;
    }


    switch(stopBits)
    {
    case STOP_1:
        new_serialArry.c_cflag &=(~CSTOPB);
        break;
    case STOP_1_5:
        break;
    case STOP_2:
        new_serialArry.c_cflag |=CSTOPB;
        break;
    default:
        new_serialArry.c_cflag &=(~CSTOPB);
        break;
    }

    switch(flow)
    {
    case FLOW_OFF:
        new_serialArry.c_cflag &=(~CRTSCTS);
        new_serialArry.c_iflag &=(~(IXON|IXOFF|IXANY));
        break;
    case FLOW_XONXOFF:
        new_serialArry.c_cflag &=(~CRTSCTS);
        new_serialArry.c_iflag |=(IXON|IXOFF|IXANY);
        break;
    case FLOW_HARDWARE:
        new_serialArry.c_cflag |=~CRTSCTS;
        new_serialArry.c_iflag &=(~(IXON|IXOFF|IXANY));
        break;
    default:
        break;
    }

    new_serialArry.c_oflag=0;
    new_serialArry.c_cc[VTIME]=time_out/100;
    tcflush(m_fd,TCIFLUSH);
    tcsetattr(m_fd,TCSANOW,&new_serialArry);

    m_notifier= new QSocketNotifier(m_fd,QSocketNotifier::Read,0);
    connect(m_notifier,SIGNAL(activated(int)),this,SLOT(remoteDateInComing()));

    return true;

}
//close
bool SerialPort::close()
{
    mutex_r.lock();

    if(m_fd!=-1)
    {
        disconnect(m_notifier,SIGNAL(activated(int)),this,SLOT(remoteDateInComing()));
        delete m_notifier;
        m_fd=-1;
        mutex_r.unlock();
        return true;
    }
    mutex_r.unlock();
    return false;
}
//recive data
void SerialPort::remoteDateInComing()
{

    unsigned char c[1024];
    int n= ::read(m_fd,&c,sizeof c);
    mutex_r.lock();
    for(int i=0;i<n;i++)
    {
        rev_buf->append(c[i]);

    }
    mutex_r.unlock();
    emit hasdata();


}
//write data
int SerialPort::write(QByteArray buf)
{

    mutex_r.lock();
    int ret;
    ret=0;
    if(m_fd!=-1)
    {        

               ret= :: write(m_fd,buf.data(),buf.length());
    }

    mutex_r.unlock();


    return ret;
}

QByteArray SerialPort::read()
{
    mutex_r.lock();
    QByteArray retByteArray;
    if(rev_buf->isEmpty())
    {
        retByteArray.append("aaa");
        retByteArray.clear();
    }else
    {
        //RECEIVE 00 ERROR 2019/2/19  retByteArray.append(rev_buf->data())
        retByteArray.append(rev_buf->data(),rev_buf->size());
        rev_buf->clear();
    }
    mutex_r.unlock();

    return retByteArray;

}

这个代码解决我当时的问题,我也修改了一下,当时还是有个bug的

在这里插入图片描述

当串口数据中有 00 时 他会解析不正确,改完就ok了,正常使用

我放到github:

https://github.com/shenmingyi/SerialPort

如果对你有帮助请给我点个star 星

  • 17
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值