Qt下实现欧姆龙PLC 串口发送HOSTLINK(FINS)模式


前言

本文讲述了Qt下模拟串口调试工具发送HOSTLINK(FINS)模式,主要进行了HR保持区的字和位的读写,对HOSTLINK协议中校验码(FCS)的计算方式进行了展示,详情可见下文代码,希望可以帮助到大家,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、HOSTLINK协议说明

HOSTLINK(FINS)命令细化的格式内容如下图所示
请添加图片描述
这里对FINS的命令格式进行解释(详细内容可见说明书)
(a)、command code(命令代码)
0101 :读命令
0102 :写命令
(b)、IO Memory Area Code(内存区域地址)
WR(Word):B1
WR(Bit):31
HR(Word):B2
HR(Bit):32
… …

此处以示例来进行上述格式说明:
//单写HR字地址(HR1写入数据1) 写:0102 字:B2
@ 00 FA 0 00 00 00 00 0102 B2 00 01(address) 00 00 01 0001(data) **(FCS) *\CR

//单读HR字地址(读取HR1地址上的数值) 读:0101 字:B2
@ 00 FA 0 00 00 00 00 0101 B2 00 01(address) 00 00 01 **(FCS) *\CR

//单写HR位地址(对HR1.01位写入数据1) 写:0102 位:32
@ 00 FA 0 00 00 00 00 0102 32 00 0101(address) 00 01 01(data) **(FCS) *\CR

//单读HR位地址(读取HR1.01位上的数值) 读:0101 位:32
@ 00 FA 0 00 00 00 00 0101 32 00 0101(address) 00 01 **(FCS) *\CR

二、校验码(FCS)计算

协议中FCS栏位:占用两个字符,取值为从@开始到正文结束的所有字符的ASCⅡ码按位异或运算的结果。计算校验码的步骤:
1.先进行输入地址位的转换
2.界面上显示的是ASCII字符,将界面上字符转化为十进制后进行按位异或运算
3.按位运算后的结果转换为16进制即为校验码

三、示例完整代码

1.示例中用到了串口相关函数,所以需要在pro中添加下列代码:

QT       += serialport

2.serialport.h

#ifndef SERIALPORT_H
#define SERIALPORT_H

#include <QWidget>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class SerialPort; }
QT_END_NAMESPACE

class SerialPort : public QWidget
{
    
    
    Q_OBJECT

public:
    SerialPort(QWidget *parent = nullptr);
    ~SerialPort();

    void initWidget();

private slots:
    void slot_serialRead();
    void slot_writeHRWordData(int address, int numWrite);
    void slot_readHRWordData(int address);
    void slot_writeHRBitData(int address, int bit, int numWrite);
    void slot_readHRBitData(int address, int bit);

    void on_pb_refresh_clicked();
    void on_pb_operate_clicked();
    void on_pb_send_clicked();

    void on_rb_read_clicked();
    void on_rb_write_clicked();

private:
    Ui::SerialPort *ui;

    QSerialPort *serial;
};
#endif // SERIALPORT_H

3.serialport.cpp

#include "serialport.h"
#include "ui_serialport.h"

SerialPort::SerialPort(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::SerialPort)
{
    
    
    ui->setupUi(this);
    this->initWidget();
}

SerialPort::~SerialPort()
{
    
    
    delete ui;
}

void SerialPort::initWidget()
{
    
    
    this->setWindowTitle("HOSTLINK(FINS)读写测试");
    setFixedSize(this->width(),this->height());

    ui->rb_read->setChecked(true);
    ui->le_num->setEnabled(false);
    ui->pb_send->setEnabled(false);

    //初始化串口
    serial = new QSerialPort(this);
    connect(serial,SIGNAL(readyRead()),this,SLOT(slot_serialRead()));
}

void SerialPort::slot_serialRead()
{
    
    
    QByteArray receiveBuf = serial->readAll();
    QString receiveStr = QString(receiveBuf);
    //qDebug()<<"receiveStr:"<<receiveStr;

    int sizeNum = receiveStr.size();
    QString showStr = receiveStr.left(sizeNum - 1);
    ui->plainTextEdit->appendPlainText("接收命令:\n" + showStr + "\\CR");

    QString leftStr = receiveStr.left(sizeNum - 4);
    //qDebug()<<"leftStr:"<<leftStr;

    QString rightStr = leftStr.right(sizeNum - 4 - 23);
    //qDebug()<<"receiveStr:"<<receiveStr<<"   leftStr:"<<leftStr<<"   rightStr:"<<rightStr;

    //rightStr需要视情况而定
    ui->le_num->setText(rightStr);
}

//单写HR字地址
void SerialPort::slot_writeHRWordData(int address,int numWrite)
{
    
    
    //H保持区   字:B2 位:32
    //@ 00 FA 0 00 00 00 00 0102 B2 00 01(address) 00 00 01 0001(data) **(FCS) *\CR
    //QString testStr = "@00FA0000000000102B200010000010001";

    //address
    QString startStr = "@00FA0000000000102B200";
    int adsNum[2];
    QByteArray hrBa;
    hrBa.setNum(address,16);
    if(address < 16)
    {
    
    
        adsNum[0] = 0;
        adsNum[1] = address;
        startStr.append("0" + QString(hrBa) + "000001");
    }
    else
    {
    
    
        adsNum[0] = (int)hrBa.at(0);
        adsNum[1] = (int)hrBa.at(1);
        startStr.append(QString(hrBa) + "000001");
    }
    //qDebug()<<"num[0]:"<<num[0]<<"   num[1]:"<<num[1];

    //numWrite 根据写入值长度变化
#if 0
    QString numStr = QString::number(numWrite);
    QByteArray numBa = numStr.toLatin1();
    qDebug()<<"numBa:"<<numBa;
    int numSize = numStr.size();
    int numEnd = numSize;
    //qDebug()<<"numSize:"<<numSize;
    if(numSize%2)
    {
    
    
        numEnd = numSize + 1;
    }
    //qDebug()<<"numEnd:"<<numEnd;

    int numNum[numEnd];
    if(numSize%2)
    {
    
    
        numNum[0] = 0;
        for(int i=1;i<numEnd;i++)
        {
    
    
            numNum[i] = (int)numBa.at(i-1);
        }
        startStr.append("0" + QString(numBa));
    }
    else
    {
    
    
        for(int i=0;i<numEnd;i++)
        {
    
    
            numNum[i] = (int)numBa.at(i);
        }
        startStr.append(QString(numBa));
    }
#else
    QString finStr = "";
    QString numStr = QString::number(numWrite);
    int numSize = numStr.size();
    if(numSize < 4)
    {
    
    
        for(int i=numSize;i<4;i++)
        {
    
    
            finStr.append("0");
        }
        finStr += numStr;
    }
    else if(numSize == 4)
    {
    
    
        finStr = numStr;
    }
    else if(numSize == 5)
    {
    
    
        finStr = "0" + numStr;
    }
    else if(numSize == 6)
    {
    
    
        finStr = numStr;
    }
    else
    {
    
    
        finStr = "0000";
    }
    QByteArray numBa = finStr.toLatin1();
    //qDebug()<<"numBa:"<<numBa;

    int numEnd = finStr.size();
    //qDebug()<<"numEnd:"<<numEnd;
    int numNum[numEnd];
    for(int i=0;i<numEnd;i++)
    {
    
    
        numNum[i] = (int)numBa.at(i);
    }
    startStr.append(QString(numBa));
#endif

    quint8 sendBuf[30+numEnd];
    memset(sendBuf+numEnd,0,30+numEnd);
    sendBuf[0] = (quint8)0x40;   //@   64
    sendBuf[1] = (quint8)0x30;   //0   48
    sendBuf[2] = (quint8)0x30;   //0   48
    sendBuf[3] = (quint8)0x46;   //F   70
    sendBuf[4] = (quint8)0x41;   //A   65
    sendBuf[5] = (quint8)0x30;   //0   48
    sendBuf[6] = (quint8)0x30;   //0   48
    sendBuf[7] = (quint8)0x30;   //0   48
    sendBuf[8] = (quint8)0x30;   //0   48
    sendBuf[9] = (quint8)0x30;   //0   48
    sendBuf[10] = (quint8)0x30;   //0   48
    sendBuf[11] = (quint8)0x30;   //0   48
    sendBuf[12] = (quint8)0x30;   //0   48
    sendBuf[13] = (quint8)0x30;   //0   48
    sendBuf[14] = (quint8)0x30;   //0   48
    sendBuf[15] = (quint8)0x31;   //1   49
    sendBuf[16] = (quint8)0x30;   //0   48
    sendBuf[17] = (quint8)0x32;   //2   50
    sendBuf[18] = (quint8)0x42;   //B   66
    sendBuf[19] = (quint8)0x32;   //2   50
    sendBuf[20] = (quint8)0x30;   //0   48
    sendBuf[21] = (quint8)0x30;   //0   48
    sendBuf[22] = (quint8)adsNum[0];   //0   48
    sendBuf[23] = (quint8)adsNum[1];   //1   49
    sendBuf[24] = (quint8)0x30;   //0   48
    sendBuf[25] = (quint8)0x30;   //0   48
    sendBuf[26] = (quint8)0x30;   //0   48
    sendBuf[27] = (quint8)0x30;   //0   48
    sendBuf[28] = (quint8)0x30;   //0   48
    sendBuf[29] = (quint8)0x31;   //1   49
    for(int i=0;i<numEnd;i++)   //data   1234
    {
    
    
        sendBuf[30+i] = numNum[i];
    }

    quint8 fcsNum = 0;
    for(int i=0;i<30+numEnd;i++)
    {
    
    
        fcsNum ^= sendBuf[i];
    }
    QByteArray fcsBa;
    fcsBa.setNum(fcsNum,16);
    //qDebug()<<"fcsBa:"<<fcsBa;

    QString scsStr = "";
    if(fcsBa.size() == 1)
    {
    
    
        scsStr = "0" + QString(fcsBa);
    }
    else
    {
    
    
        scsStr = QString(fcsBa);
    }
    //qDebug()<<"ab:"<<ab;

    startStr.append(scsStr + "*\r");
    QString lastStr = startStr.toUpper();
    //qDebug()<<"lastStr:"<<lastStr;

    int sizeNum = lastStr.size();
    QString showStr = lastStr.left(sizeNum - 1);
    ui->plainTextEdit->appendPlainText("发送写命令:\n" + showStr + "\\CR");

    char *writeStr;
    QByteArray writeBa = lastStr.toLatin1();
    writeStr = writeBa.data();
    qDebug()<<"writeStr:"<<writeStr;

    serial->write(writeStr);
}

//单读HR字地址
void SerialPort::slot_readHRWordData(int address)
{
    
    
    //H保持区   字:B2 位:32
    //@ 00 FA 0 00 00 00 00 0101 B2 00 01(address) 00 00 01 **(FCS) *\CR
    //QString testStr = "@00FA0000000000101B20001000001";

    QString startStr = "@00FA0000000000101B200";

    //address
    int adsNum[2];
    QByteArray hrBa;
    hrBa.setNum(address,16);
    if(address < 16)
    {
    
    
        adsNum[0] = 0;
        adsNum[1] = address;
        startStr.append("0" + QString(hrBa) + "000001");
    }
    else
    {
    
    
        adsNum[0] = (int)hrBa.at(0);
        adsNum[1] = (int)hrBa.at(1);
        startStr.append(QString(hrBa) + "000001");
    }
    //qDebug()<<"num[0]:"<<num[0]<<"   num[1]:"<<num[1];

    quint8 sendBuf[30];
    memset(sendBuf,0,30);
    sendBuf[0] = (quint8)0x40;   //@   64
    sendBuf[1] = (quint8)0x30;   //0   48
    sendBuf[2] = (quint8)0x30;   //0   48
    sendBuf[3] = (quint8)0x46;   //F   70
    sendBuf[4] = (quint8)0x41;   //A   65
    sendBuf[5] = (quint8)0x30;   //0   48
    sendBuf[6] = (quint8)0x30;   //0   48
    sendBuf[7] = (quint8)0x30;   //0   48
    sendBuf[8] = (quint8)0x30;   //0   48
    sendBuf[9] = (quint8)0x30;   //0   48
    sendBuf[10] = (quint8)0x30;   //0   48
    sendBuf[11] = (quint8)0x30;   //0   48
    sendBuf[12] = (quint8)0x30;   //0   48
    sendBuf[13] = (quint8)0x30;   //0   48
    sendBuf[14] = (quint8)0x30;   //0   48
    sendBuf[15] = (quint8)0x31;   //1   49
    sendBuf[16] = (quint8)0x30;   //0   48
    sendBuf[17] = (quint8)0x31;   //1   49
    sendBuf[18] = (quint8)0x42;   //B   66
    sendBuf[19] = (quint8)0x32;   //2   50
    sendBuf[20] = (quint8)0x30;   //0   48
    sendBuf[21] = (quint8)0x30;   //0   48
    sendBuf[22] = (quint8)adsNum[0];   //0   48
    sendBuf[23] = (quint8)adsNum[1];   //1   49
    sendBuf[24] = (quint8)0x30;   //0   48
    sendBuf[25] = (quint8)0x30;   //0   48
    sendBuf[26] = (quint8)0x30;   //0   48
    sendBuf[27] = (quint8)0x30;   //0   48
    sendBuf[28] = (quint8)0x30;   //0   48
    sendBuf[29] = (quint8)0x31;   //1   49

    quint8 fcsNum = 0;
    for(int i=0;i<30;i++)
    {
    
    
        fcsNum ^= sendBuf[i];
    }
    QByteArray fcsBa;
    fcsBa.setNum(fcsNum,16);
    //qDebug()<<"fcs:"<<fcs;

    QString scsStr = "";
    if(fcsBa.size() == 1)
    {
    
    
        scsStr = "0" + QString(fcsBa);
    }
    else
    {
    
    
        scsStr = QString(fcsBa);
    }
    //qDebug()<<"ab:"<<ab;

    startStr.append(scsStr + "*\r");
    QString lastStr = startStr.toUpper();
    //qDebug()<<"lastStr:"<<lastStr;

    int sizeNum = lastStr.size();
    QString showStr = lastStr.left(sizeNum - 1);
    ui->plainTextEdit->appendPlainText("发送读命令:\n" + showStr + "\\CR");

    char *readStr;
    QByteArray readBa = lastStr.toLatin1();
    readStr = readBa.data();
    qDebug()<<"readStr:"<<readStr;

    serial->write(readStr);
}

//单写HR位地址
void SerialPort::slot_writeHRBitData(int address,int bit,int numWrite)
{
    
    
    //H保持区   字:B2 位:32
    //@ 00 FA 0 00 00 00 00 0102 32 00 1900(address) 00 01 01(data) **(FCS) *\CR
    //QString testStr = "@00FA000000000010232001900000101";

    //address
    QString startStr = "@00FA00000000001023200";
    int adsNum[2];
    QByteArray hrBa;
    hrBa.setNum(address,16);
    if(address < 16)
    {
    
    
        adsNum[0] = 0;
        adsNum[1] = address;
        startStr.append("0" + QString(hrBa));
    }
    else
    {
    
    
        adsNum[0] = (int)hrBa.at(0);
        adsNum[1] = (int)hrBa.at(1);
        startStr.append(QString(hrBa));
    }
    //qDebug()<<"num[0]:"<<num[0]<<"   num[1]:"<<num[1];

    //bit
    int bitNum[2];
    QByteArray bitBa;
    bitBa.setNum(bit,16);
    bitNum[0] = 0;
    bitNum[1] = bit;
    startStr.append("0" + QString(bitBa) + "0001");

    //numWrite
    QString numStr = QString::number(numWrite);
    int numNum[2];
    numNum[0] = 0;
    numNum[1] = numWrite;
    startStr.append("0" + numStr);

    quint8 sendBuf[32];
    memset(sendBuf,0,32);
    sendBuf[0] = (quint8)0x40;   //@   64
    sendBuf[1] = (quint8)0x30;   //0   48
    sendBuf[2] = (quint8)0x30;   //0   48
    sendBuf[3] = (quint8)0x46;   //F   70
    sendBuf[4] = (quint8)0x41;   //A   65
    sendBuf[5] = (quint8)0x30;   //0   48
    sendBuf[6] = (quint8)0x30;   //0   48
    sendBuf[7] = (quint8)0x30;   //0   48
    sendBuf[8] = (quint8)0x30;   //0   48
    sendBuf[9] = (quint8)0x30;   //0   48
    sendBuf[10] = (quint8)0x30;   //0   48
    sendBuf[11] = (quint8)0x30;   //0   48
    sendBuf[12] = (quint8)0x30;   //0   48
    sendBuf[13] = (quint8)0x30;   //0   48
    sendBuf[14] = (quint8)0x30;   //0   48
    sendBuf[15] = (quint8)0x31;   //1   49
    sendBuf[16] = (quint8)0x30;   //0   48
    sendBuf[17] = (quint8)0x32;   //2   50
    sendBuf[18] = (quint8)0x33;   //3   51
    sendBuf[19] = (quint8)0x32;   //2   50
    sendBuf[20] = (quint8)0x30;   //0   48
    sendBuf[21] = (quint8)0x30;   //0   48
    sendBuf[22] = (quint8)adsNum[0];   //1   49
    sendBuf[23] = (quint8)adsNum[1];   //9   57
    sendBuf[24] = (quint8)bitNum[0];   //0   48
    sendBuf[25] = (quint8)bitNum[1];   //0   48
    sendBuf[26] = (quint8)0x30;   //0   48
    sendBuf[27] = (quint8)0x30;   //0   48
    sendBuf[28] = (quint8)0x30;   //0   48
    sendBuf[29] = (quint8)0x31;   //1   49
    sendBuf[30] = (quint8)numNum[0];   //0   48
    sendBuf[31] = (quint8)numNum[1];   //1   49

    quint8 fcsNum = 0;
    for(int i=0;i<32;i++)
    {
    
    
        fcsNum ^= sendBuf[i];
    }
    QByteArray fcsBa;
    fcsBa.setNum(fcsNum,16);
    //qDebug()<<"fcsBa:"<<fcsBa;

    QString scsStr = "";
    if(fcsBa.size() == 1)
    {
    
    
        scsStr = "0" + QString(fcsBa);
    }
    else
    {
    
    
        scsStr = QString(fcsBa);
    }
    //qDebug()<<"ab:"<<ab;

    startStr.append(scsStr + "*\r");
    QString lastStr = startStr.toUpper();
    //qDebug()<<"lastStr:"<<lastStr;

    int sizeNum = lastStr.size();
    QString showStr = lastStr.left(sizeNum - 1);
    ui->plainTextEdit->appendPlainText("发送写命令:\n" + showStr + "\\CR");

    char *writeStr;
    QByteArray writeBa = lastStr.toLatin1();
    writeStr = writeBa.data();
    qDebug()<<"writeStr:"<<writeStr;

    serial->write(writeStr);
}

//单读HR位地址
void SerialPort::slot_readHRBitData(int address,int bit)
{
    
    
    //H保持区   字:B2 位:32
    //@ 00 FA 0 00 00 00 00 0101 32 00 1900(address) 00 01 **(FCS) *\CR
    //QString testStr = "@00FA0000000000102320019000001";

    //address
    QString startStr = "@00FA00000000001013200";
    int adsNum[2];
    QByteArray hrBa;
    hrBa.setNum(address,16);
    if(address < 16)
    {
    
    
        adsNum[0] = 0;
        adsNum[1] = address;
        startStr.append("0" + QString(hrBa));
    }
    else
    {
    
    
        adsNum[0] = (int)hrBa.at(0);
        adsNum[1] = (int)hrBa.at(1);
        startStr.append(QString(hrBa));
    }
    //qDebug()<<"num[0]:"<<num[0]<<"   num[1]:"<<num[1];

    //bit
    int bitNum[2];
    QByteArray bitBa;
    bitBa.setNum(bit,16);
    bitNum[0] = 0;
    bitNum[1] = bit;
    startStr.append("0" + QString(bitBa) + "0001");

    quint8 sendBuf[30];
    memset(sendBuf,0,32);
    sendBuf[0] = (quint8)0x40;   //@   64
    sendBuf[1] = (quint8)0x30;   //0   48
    sendBuf[2] = (quint8)0x30;   //0   48
    sendBuf[3] = (quint8)0x46;   //F   70
    sendBuf[4] = (quint8)0x41;   //A   65
    sendBuf[5] = (quint8)0x30;   //0   48
    sendBuf[6] = (quint8)0x30;   //0   48
    sendBuf[7] = (quint8)0x30;   //0   48
    sendBuf[8] = (quint8)0x30;   //0   48
    sendBuf[9] = (quint8)0x30;   //0   48
    sendBuf[10] = (quint8)0x30;   //0   48
    sendBuf[11] = (quint8)0x30;   //0   48
    sendBuf[12] = (quint8)0x30;   //0   48
    sendBuf[13] = (quint8)0x30;   //0   48
    sendBuf[14] = (quint8)0x30;   //0   48
    sendBuf[15] = (quint8)0x31;   //1   49
    sendBuf[16] = (quint8)0x30;   //0   48
    sendBuf[17] = (quint8)0x31;   //1   49
    sendBuf[18] = (quint8)0x33;   //3   51
    sendBuf[19] = (quint8)0x32;   //2   50
    sendBuf[20] = (quint8)0x30;   //0   48
    sendBuf[21] = (quint8)0x30;   //0   48
    sendBuf[22] = (quint8)adsNum[0];   //1   49
    sendBuf[23] = (quint8)adsNum[1];   //9   57
    sendBuf[24] = (quint8)bitNum[0];   //0   48
    sendBuf[25] = (quint8)bitNum[1];   //0   48
    sendBuf[26] = (quint8)0x30;   //0   48
    sendBuf[27] = (quint8)0x30;   //0   48
    sendBuf[28] = (quint8)0x30;   //0   48
    sendBuf[29] = (quint8)0x31;   //1   49

    quint8 fcsNum = 0;
    for(int i=0;i<30;i++)
    {
    
    
        fcsNum ^= sendBuf[i];
    }
    QByteArray fcsBa;
    fcsBa.setNum(fcsNum,16);
    //qDebug()<<"fcsBa:"<<fcsBa;

    QString scsStr = "";
    if(fcsBa.size() == 1)
    {
    
    
        scsStr = "0" + QString(fcsBa);
    }
    else
    {
    
    
        scsStr = QString(fcsBa);
    }
    //qDebug()<<"ab:"<<ab;

    startStr.append(scsStr + "*\r");
    QString lastStr = startStr.toUpper();
    //qDebug()<<"lastStr:"<<lastStr;

    int sizeNum = lastStr.size();
    QString showStr = lastStr.left(sizeNum - 1);
    ui->plainTextEdit->appendPlainText("发送读命令:\n" + showStr + "\\CR");

    char *readStr;
    QByteArray readBa = lastStr.toLatin1();
    readStr = readBa.data();
    qDebug()<<"readStr:"<<readStr;

    serial->write(readStr);
}

void SerialPort::on_pb_refresh_clicked()
{
    
    
    ui->cb_port->clear();
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
    
    
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
    
    
            ui->cb_port->addItem(info.portName());
            serial.close();
        }
    }
}

void SerialPort::on_pb_operate_clicked()
{
    
    
    if(ui->cb_port->currentText().isEmpty())
    {
    
    
        QMessageBox::information(this, tr("提示"),"请先刷新并进行串口选择!");
        return;
    }

    if(ui->pb_operate->text() == QString("OPEN"))
    {
    
    
        QString portName = ui->cb_port->currentText();
        QString baudRate = ui->cb_baud->currentText();
        qDebug()<<"portName:"<<portName<<"   baudRate:"<<baudRate;

        QSerialPortInfo info(portName);
        if(info.isBusy())
        {
    
    
            qDebug()<<"The serial port is occupied"<<portName;
            return;
        }

        serial->setPortName(portName);
        serial->setBaudRate(baudRate.toInt());
        serial->setStopBits(QSerialPort::TwoStop);
        serial->setDataBits(QSerialPort::Data7);
        serial->setParity(QSerialPort::EvenParity);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        bool flag = serial->open(QIODevice::ReadWrite);
        if(!flag)
        {
    
    
            qDebug()<<QString("Failed to open serial port:")<<portName<<serial->errorString();
            serial->clearError();
            ui->pb_send->setEnabled(false);
        }
        else
        {
    
    
            qDebug()<<QString("The serial port is open:")<<portName;
            ui->pb_operate->setText("CLOSE");
            ui->pb_send->setEnabled(true);
        }
    }
    else
    {
    
    
        ui->pb_operate->setText("OPEN");
        serial->close();
        ui->pb_send->setEnabled(false);
    }
}

void SerialPort::on_pb_send_clicked()
{
    
    
    //1.界面上显示的是ASCII字符
    //2.计算校验码的步骤
    //3.先进行输入地址位的转换
    //4.将界面上字符转化为十进制后进行按位异或运算
    //5.按位运算后的结果转换为16进制即为校验码

    int address = ui->le_address->text().toInt();
    int bit = ui->le_bit->text().toInt();
    int numWrite = ui->le_num->text().toInt();

    //单读
    if(ui->rb_read->isChecked())
    {
    
    
        if(ui->le_bit->text().isEmpty())
        {
    
    
            slot_readHRWordData(address);
        }
        else
        {
    
    
            slot_readHRBitData(address,bit);
        }
    }

    //单写
    if(ui->rb_write->isChecked())
    {
    
    
        if(ui->le_bit->text().isEmpty())
        {
    
    
            slot_writeHRWordData(address,numWrite);
        }
        else
        {
    
    
            slot_writeHRBitData(address,bit,numWrite);
        }
    }
}

void SerialPort::on_rb_read_clicked()
{
    
    
    ui->le_num->setEnabled(false);
}

void SerialPort::on_rb_write_clicked()
{
    
    
    ui->le_num->setEnabled(true);
}

4.serialport.ui
请添加图片描述

四、下载链接

我的示例百度网盘链接:https://pan.baidu.com/s/1eGnt6I7UVeN5p3n4bvLVTA
提取码:xxcj


总结

本文实现的与欧姆龙PLC进行的通信也是比较简单的,使用串口进行命令的发送,前提是对HOSTLINK协议有相应的了解,然后去实现该协议命令的组装,其中需要注意的一个点是FCS(校验码)的获取。本文还存在的局限是只进行了HR区域的读写,并且只能进行单独某地址或某位的读写,所以想要实现更多区域的读写就需要进行改进了,这里提供这样一个示例,希望可以帮助到大家。


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考博客:
欧姆龙plc交互协议hostlink
基于HostLink协议的Fins命令读写

猜你喜欢

转载自blog.csdn.net/XCJandLL/article/details/128786473
今日推荐