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

news2024/11/17 7:39:25

文章目录

  • 前言
  • 一、HOSTLINK协议说明
  • 二、校验码(FCS)计算
  • 三、示例完整代码
  • 四、下载链接
  • 总结


前言

本文讲述了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命令读写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次CPU飚高以及排查过程

一.cpu突然飚高 收到系统频发的cpu超过90%的告警.虽然是在非线上环境出现.接到告警后第一反应还是去重启了机器,重启后cpu如期的下降了下来.以为能高枕无忧,不过一会儿还是收到了告警. 二.排查 2.1 top 指令查看物理机进程id 申请了堡垒机权限登上机器 top指令后.如下确实发…

微服务,Docker, k8s,Cloud native 云原生的简易发展史

微服务发展史 2005年&#xff1a;Dr. PeterRodgers在Web ServicesEdge大会上提出了“Micro-Web-Services”的概念。2011年&#xff1a;一个软件架构工作组使用了“microservice”一词来描述一种架构模式。2012年&#xff1a;同样是这个架构工作组&#xff0c;正式确定用“micr…

万字详解 C 语言文件操作

目录 一、什么是文件&#xff1f; 1.1 - 文件和流的基本概念 1.2 - 文件的分类 1.3 - 文件名 二、缓冲文件系统和非缓冲文件系统 三、文件指针类型 四、文件的打开和关闭 4.1 - fopen 4.2 - fclose 五、文件的顺序读写 5.1 - 字符输出函数 fputc 5.2 - 字符输入函数…

【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(上)

目录 一、k8s 助力 DevOps 在企业落地实践 1.1 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 1.2 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 1.3 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 1.4 什么是 DevOps&#xff1f; …

【JavaScript】原型链

文章目录构造函数原型对象访问机制内置构造函数一切皆对象原型链构造函数 - 本质还是一个函数- 和 new 关键字连用- 特点1. 自动创建一个对象2. 自动返回一个对象3. 让函数的this指向这个对象 书写构造函数的时候1. 属性写在函数内2. 方法写在原型上构造函数的不合理 把方法写在…

Android studio 护眼模式配置、字体大小设置、内存大小设置等各类疑难杂症

Android studio 4.1 1、左边目录栏颜色配置&#xff1a; 2、代码编辑区域背景色设置 3、控制台背景色设置 4、菜单栏、工具栏、左边栏字体大小设置 5、编码区字体大小设置 6、修改内存大小、显示内存 例如&#xff1a;修改android-studio/bin/studio.vmoptions studio64.vmop…

NANK南卡护眼台灯Pro评测,护眼台灯天花板般存在!

现代大环境下&#xff0c;生活节奏和压力的不断加快加重&#xff0c;如今的手机、电脑屏幕以及长时间的工作学习都会出现用眼过度的问题&#xff0c;久而久之&#xff0c;各种眼睛刺痛、干涩、肿胀等近视问题接踵而至。为了保障自己的健康&#xff0c;近些年&#xff0c;人们纷…

回归预测 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入单输出

回归预测 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入单输出 目录回归预测 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入单输出预测效果基本介绍模型描述程序设计参考文献预测效果 基本介绍 MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入单输出。 1 .data为…

基础课程11:调试工具

目标 有时事情不会按照预期进行&#xff0c;从总线(如果有的话)检索到的错误消息不能提供足够的信息。幸运的是&#xff0c;GStreamer附带了大量调试信息&#xff0c;这些信息通常会提示问题可能是什么。本教程展示了: 如何从GStreamer获取更多调试信息。 如何将自己的调试信…

电力电子器件简介

文章目录1、二极管2、BJT3、晶闸管&#xff08;SCR&#xff09;4、TRIAC5、GTO&#xff08;全控器件&#xff09;6、功率MOSFET&#xff08;开关速度快、电压驱动更容易&#xff09;7、IGBT8、总结![在这里插入图片描述](https://img-blog.csdnimg.cn/1d309b3d449040788c6437f8…

【胖虎的逆向之路】04——脱壳(一代壳)原理脱壳相关概念详解

【胖虎的逆向之路】04——脱壳&#xff08;一代壳&#xff09;原理&脱壳相关概念详解 【胖虎的逆向之路】01——动态加载和类加载机制详解 【胖虎的逆向之路】02——Android整体加壳原理详解&实现 【胖虎的逆向之路】03——Android一代壳脱壳办法&实操 文章目录【…

高速路如何避免ETC车辆漏计问题,ETC通道出入车辆校准看板

人群密集场所事故预防措施和应急管理方案的制定&#xff0c;对每一个交通枢纽和大型社会活动场所都显得尤为重要。对于交通管理部门来说&#xff0c;获取准确、可靠的交通数据已经变得越来越重要。 所以呢&#xff0c;ETC出入车辆校准看板是必要的。ETC出入车辆校准看板&#x…

如何使用路由策略解决 ISIS与OSPF双点双向产生的次优路径、环路隐患?

3.1.0 如何使用路由策略解决 ISIS与OSPF双点双向产生的次优路径、环路隐患 一、双点双向中的次优路径解决方法 双点双向中由于默认路由优先级造成次优路径的产生&#xff0c;而解决的方法就是修改路由优先级。 双点双向错误的解决方法 关于修改路由优先级&#xff0c;需要注…

2022 医疗卫生行业应急响应形势分析报告 脱敏板

声明 本文是学习2022医疗卫生行业网络安全分析报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 医疗卫生行业应急响应形势分析 2021年1-12月&#xff0c;奇安信集团安服团队共参与和处置全国范围内医疗卫生行业网络安全应急响应事件84起&#xf…

is not defined at HTMLInputElement.onclick

vue项目中一小部分功能想要使用原生的onclick 事件&#xff0c;发现报错Uncaught ReferenceError: 函数名 is not defined at HTMLInputElement.onclick搜索了相关blog&#xff0c;得出结论是onclick事件调用的方法必须是全局变量或者说是window的方法解决方法&#xff1a;将cl…

leetcode:43. 字符串相乘(附加一些C++string其他小练习)

目录 一.leetcode&#xff1a;43. 字符串相乘 1.问题描述 2.问题分析 3.问题求解 二. leetcode&#xff1a;541. 反转字符串 II 1.问题描述 2.题解 三. leetcode&#xff1a;125. 验证回文串 1.问题描述 2.双指针法求解 一.leetcode&#xff1a;43. 字符串相乘 43…

数据结构(括号匹配与表达式计算)

目录 括号配对 括号匹配算法 表达式计算 后缀式的计算 中缀式转后缀式 括号配对 编译器做语法检查的任务之一是检查符号是否配对&#xff0c;最简单的符号匹配问题是括号是否匹配&#xff0c;如开括号( 及{ 后面必须依次跟随相应的闭括号 }及 )。 如下段程序中的括号、引号…

谷歌竞价账户效果不好的原因?

很多外贸企业喜欢用谷歌竞价来推广自己的网站&#xff0c;提升自己的竞争力。是一种能很快看到效果的宣传方式。但是很多公司在谷歌竞价上投入了大量的资金&#xff0c;却收效甚微。为什么&#xff1f;下面我们来看看如何解决我们在google竞价推广中会遇到的一些问题。很多人在…

Linux的文件权限理解

目录 前言 1、用户、用户组、其他人 1.1用户、用户组、其他人之间的概念理解 1.2Linux系统中有用户身份与用户组记录的文件 2、Linux文件权限概念 第一列 第二列 第三列 第四列 第五列 第六列 第七列 Linux文件权限的重要性 3、Linux的目录与文件的权限意义 权限…

计算机图形学 第5章 二维变换与裁剪到Cohen-Sutherland直线裁剪算法

目录学习目标前驱知识规范化齐次坐标二维几何变换矩阵物体变换与坐标变换二维几何变换二维图形基本几何变换矩阵平移变换矩阵比例变换矩阵旋转变换矩阵反射变换矩阵错切变换矩阵二维仿射变换二维复合变换相对于任意方向的二维几何变换二维图形裁剪世界坐标系2.用户坐标系观察坐…