Qt で Omron PLC シリアル ポート送信 HOSTLINK (FINS) モードを実現


序文

この記事では、Qt 上の模擬シリアル ポート デバッグ ツールによって送信される HOSTLINK (FINS) モードについて説明します。主に HR 保持領域のワードとビットの読み書きと、HOSTLINK プロトコルのチェック コード (FCS) の計算方法を示します。詳細については以下を参照してください。このコードは、皆さんのお役に立てれば幸いです。間違いがあれば、皆さんの批判と修正を歓迎します。

事業効果
画像の説明を追加してください


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

1. HOSTLINKプロトコルの説明

HOSTLINK(FINS)コマンドの詳細フォーマットを下図に示します
画像の説明を追加してください
FINSコマンドフォーマットの説明(詳細はマニュアルを参照)
(a)コマンドコード(コマンドコード)
0101:リードコマンド
0102:ライトコマンド
(b)、IOメモリエリアコード(メモリエリアアドレス)
WR(Word): B1
WR(Bit): 31
HR(Word): B2
HR(Bit): 32
… …

上記の形式を説明する例を次に示します。
//単一書き込み HR ワード アドレス (HR1 書き込みデータ 1) write: 0102 word: 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(アドレス) 00 00 01 **(FCS) *\CR

//単一書き込み HR ビット アドレス (HR1.01 ビットへのデータ 1 の書き込み) Write: 0102 bit: 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

2. チェックコード(FCS)の計算

契約書の FCS フィールド: 2 文字を占め、値は @ からテキストの末尾までのすべての文字の ASCII コードのビット単位の XOR 演算の結果です。チェックコードの計算手順:
1. まず入力アドレスのビットを変換します
2. ASCII 文字がインターフェイスに表示されます インターフェイス上の文字を 10 進数に変換し、ビットごとの XOR 演算を実行します 3. ビットごとの演算の結果が変換され
ます16進数への変換はチェックコードです

3. 完全なコードの例

1. この例ではシリアル ポート関連の関数が使用されているため、次のコードを Pro に追加する必要があります。

QT       += serialport

2.シリアルポート.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.シリアルポート.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.シリアルポート.ui
画像の説明を追加してください

4. ダウンロードリンク

私の Baidu ネットワーク ディスク リンクの例: https://pan.baidu.com/s/1eGnt6I7UVeN5p3n4bvLVTA
抽出コード: xxcj


要約する

この記事で実現するオムロン PLC との通信も比較的単純で、シリアル ポートを使用してコマンドを送信しますが、前提として HOSTLINK プロトコルを相応に理解し、プロトコル コマンドの組み立てを実現する必要があります。注意が必要なのはFCS(スクールチェックコード)取得です。この記事の制限は、HR 領域のみを読み書きし、単一アドレスまたは特定のビットのみを読み書きできることであるため、より多くの領域を読み書きしたい場合は改善する必要があります。 , 皆様のお役に立てれば幸いです。


こんにちは:
一緒に学び、一緒に進歩しましょう。関連する質問がまだある場合は、ディスカッションのためにコメント領域にメッセージを残すことができます。

参考ブログ:
オムロン plc インタラクティブ プロトコルのホストリンクは、
HostLink プロトコルに基づいて Fins コマンドを読み書きします

おすすめ

転載: blog.csdn.net/XCJandLL/article/details/128786473