福感科技有限公司 欢迎您!
联系方式

    地址:北京市平谷区马坊镇金河北街17号院3号楼7层712

    电话:010-89968230

    网站:http://www.fgsense.com

你的位置:首页 > 新闻动态 > 行业新闻

LINUX串口通信

2024-4-15 19:45:30      点击:

serialport.h,serialport.cpp


#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;
}

Copyright 2019 www.fgsense.com

福感科技有限公司 版权所有 All Rights Reserved

京ICP备20002031号

010-89968230