Qt 串口通信之使用三菱PLC控制程序
作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
前言
上位机与PLC通信有很多种方式,比如CPU编程口、网口、串口、总线连接等等。本章节记录一下如何通过串口让PLC控制程序执行操作。博主之前写过一章使用网口与PLC通信,具体请参考:Qt使用 MX Component 插件与三菱PLC通信
功能预览

通信协议
所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,属于OSI七层参考模型中的数据链路层。目前,采用的通信协议有两类:异步协议和同步协议。
总的来说,通讯协议就是通讯双方共同遵循的一套规则,定义协议的原则是尽可能的简单以提高传输率,尽可能的具有安全性保证数据传输完整正确。基于这2点规则,我们一个通讯协议应该是这样的:
头 + 数据长度 + 数据正文 + 校验
查看端口
我的代码
需要在 pro 文件中导入串口模块:
QT += serialport
serialportcontrol.h
#ifndef SERIALPORTCONTROL_H
#define SERIALPORTCONTROL_H#include
#include
#include class SerialPortControl : public QThread
{Q_OBJECT
public:explicit SerialPortControl();bool open(QString portName);void close();void writeResult(QString ret);virtual void run() override;signals:void startWork();private:QSerialPort m_serialPort;bool isStarted;
};#endif // SERIALPORTCONTROL_H
serialportcontrol.cpp
#include "serialportcontrol.h"
#include "globalfun.h"SerialPortControl::SerialPortControl()
{isStarted = false;
}bool SerialPortControl::open(QString portName)
{// 设置串口名称m_serialPort.setPortName(portName);// 设置波特率switch (GlobalValue::atm_bte) {case 0: m_serialPort.setBaudRate(QSerialPort::Baud1200); break;case 1: m_serialPort.setBaudRate(QSerialPort::Baud2400); break;case 2: m_serialPort.setBaudRate(QSerialPort::Baud4800); break;case 3: m_serialPort.setBaudRate(QSerialPort::Baud9600); break;case 4: m_serialPort.setBaudRate(QSerialPort::Baud19200); break;case 5: m_serialPort.setBaudRate(QSerialPort::Baud38400); break;case 6: m_serialPort.setBaudRate(QSerialPort::Baud57600); break;case 7: m_serialPort.setBaudRate(QSerialPort::Baud115200); break;default: m_serialPort.setBaudRate(QSerialPort::UnknownBaud); break;}// 设置数据位switch (GlobalValue::atm_dbt) {case 0: m_serialPort.setDataBits(QSerialPort::Data5); break;case 1: m_serialPort.setDataBits(QSerialPort::Data6); break;case 2: m_serialPort.setDataBits(QSerialPort::Data7); break;case 3: m_serialPort.setDataBits(QSerialPort::Data8); break;default: m_serialPort.setDataBits(QSerialPort::UnknownDataBits); break;}// 设置奇偶校验switch (GlobalValue::atm_cbt) {case 0: m_serialPort.setParity(QSerialPort::NoParity); break;case 1: m_serialPort.setParity(QSerialPort::EvenParity); break;case 2: m_serialPort.setParity(QSerialPort::OddParity); break;case 3: m_serialPort.setParity(QSerialPort::SpaceParity); break;case 4: m_serialPort.setParity(QSerialPort::MarkParity); break;default: m_serialPort.setParity(QSerialPort::UnknownParity); break;}// 设置停止位switch (GlobalValue::atm_sbt) {case 0: m_serialPort.setStopBits(QSerialPort::OneStop); break;case 1: m_serialPort.setStopBits(QSerialPort::OneAndHalfStop); break;case 2: m_serialPort.setStopBits(QSerialPort::TwoStop); break;default: m_serialPort.setStopBits(QSerialPort::UnknownStopBits); break;}// 设置流控制switch (GlobalValue::atm_fcl) {case 0: m_serialPort.setFlowControl(QSerialPort::NoFlowControl); break;case 1: m_serialPort.setFlowControl(QSerialPort::HardwareControl); break;case 2: m_serialPort.setFlowControl(QSerialPort::SoftwareControl); break;default: m_serialPort.setFlowControl(QSerialPort::UnknownFlowControl); break;}// 打开串口isStarted = m_serialPort.open(QIODevice::ReadWrite);return isStarted;
}void SerialPortControl::close()
{// 关闭串口isStarted = false;m_serialPort.close();
}void SerialPortControl::writeResult(QString ret)
{if ( m_serialPort.isOpen() ) {m_serialPort.write(ret.toLatin1());}
}void SerialPortControl::run()
{while ( isStarted ){// 读取串口QByteArray buffer = m_serialPort.readAll();QString str = QString(buffer);if ( str == "do" ) {emit startWork();}GlobalFun::bsleep(100);}
}
mainwindow.cpp
void MainWindow::initSerialport()
{qDebug() << "initSerialport !";m_spCtl = new SerialPortControl();// 获取可用串口号for ( auto &temp : QSerialPortInfo::availablePorts() ){ui->serialPortBox->addItem(temp.portName());}connect(m_spCtl, &SerialPortControl::startWork, this, [&](){ startCalculation(); }, Qt::QueuedConnection);
}
void MainWindow::on_fillData()
{......QApplication::processEvents();// 往串口里写入计算结果if ( m_spCtl->isRunning() ) {QString totalRet = ui->data_table->item(dRow, 3)->text();m_spCtl->writeResult(totalRet);}
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
