Программа нуждается в тестировании.
Реализовано и проверено: 1) Подключение устройства 2) Запись и чтение Coil и Holding регистров 3) Индикация работы МЗКТЭ и напряжения на ТЭ Реализовано и нуждается в проверке: 1) Поиск плат и установление их адресов в сети 2) Сканирование текущих настроек платы при подключении 3) Опрос текущих значений напряжений ТЭ по таймеру 4) Изменение скорости обмена, сетевого адреса плат и настройка контроля четности. #3
This commit is contained in:
parent
59e9fb65a3
commit
5b2a64a39b
@ -1,4 +1,10 @@
|
||||
QT += core gui
|
||||
QT += widgets serialport
|
||||
QT += serialbus widgets
|
||||
|
||||
requires(qtConfig(combobox))
|
||||
QT += serialport
|
||||
qtConfig(modbus-serialport): QT += serialport
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
@ -16,14 +22,22 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
devicesettingsdialog.cpp \
|
||||
main.cpp \
|
||||
m3kte.cpp
|
||||
m3kte.cpp \
|
||||
settingsdialog.cpp \
|
||||
writeregistermodel.cpp
|
||||
|
||||
HEADERS += \
|
||||
m3kte.h
|
||||
devicesettingsdialog.h \
|
||||
m3kte.h \
|
||||
settingsdialog.h \
|
||||
writeregistermodel.h
|
||||
|
||||
FORMS += \
|
||||
m3kte.ui
|
||||
devicesettingsdialog.ui \
|
||||
m3kte.ui \
|
||||
settingsdialog.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
88
M3KTE_TERM/devicesettingsdialog.cpp
Normal file
88
M3KTE_TERM/devicesettingsdialog.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "devicesettingsdialog.h"
|
||||
#include "ui_devicesettingsdialog.h"
|
||||
|
||||
DeviceSettingsDialog::DeviceSettingsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DeviceSettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
_currentBoardTimers[0] = ui->spinTimerBoard_1->value();
|
||||
_currentBoardTimers[1] = ui->spinTimerBoard_2->value();
|
||||
_currentBoardTimers[2] = ui->spinTimerBoard_3->value();
|
||||
_currentBoardTimers[3] = ui->spinTimerBoard_4->value();
|
||||
|
||||
_currentSpeed = ui->speedBox->currentText().toUInt();
|
||||
|
||||
_currentParity = ui->parityBox->currentIndex();
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
_currentAdrs[i] = i+1;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceSettingsDialog::~DeviceSettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeTimer_clicked()
|
||||
{
|
||||
_currentBoardTimers[0] = ui->spinTimerBoard_1->value();
|
||||
_currentBoardTimers[1] = ui->spinTimerBoard_2->value();
|
||||
_currentBoardTimers[2] = ui->spinTimerBoard_3->value();
|
||||
_currentBoardTimers[3] = ui->spinTimerBoard_4->value();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeSpeed_clicked()
|
||||
{
|
||||
|
||||
_currentSpeed = ui->speedBox->currentText().toUInt();
|
||||
emit speedChanged();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeParity_clicked()
|
||||
{
|
||||
_currentParity = ui->parityBox->currentData().toUInt();
|
||||
emit parityChanged();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeAdr_clicked()
|
||||
{
|
||||
BoardIdHasBeenChanged* _boardIdHasBeenChanged = new BoardIdHasBeenChanged(ui->idComboBox->currentIndex(), ui->adrSpinBox->value());
|
||||
QCoreApplication::postEvent(parent(), _boardIdHasBeenChanged);
|
||||
}
|
||||
|
||||
unsigned DeviceSettingsDialog::currentBoardTimer(unsigned short _ID)
|
||||
{
|
||||
return _currentBoardTimers[_ID];
|
||||
}
|
||||
|
||||
unsigned DeviceSettingsDialog::currentSpeed()
|
||||
{
|
||||
return _currentSpeed;
|
||||
}
|
||||
|
||||
unsigned short DeviceSettingsDialog::currentParity()
|
||||
{
|
||||
return _currentParity;
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr)
|
||||
{
|
||||
ui->speedBox->setCurrentText(QString::number(_currentSpeed=tmp_speed, 10));
|
||||
if(tmp_parity>0)
|
||||
tmp_parity--;
|
||||
ui->parityBox->setCurrentIndex(_currentParity = tmp_parity);
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
_currentAdrs[i] = tmp_adr[i];
|
||||
}
|
||||
on_idComboBox_currentIndexChanged(ui->idComboBox->currentIndex());
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_idComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
ui->adrSpinBox->setValue(_currentAdrs[index]);
|
||||
}
|
66
M3KTE_TERM/devicesettingsdialog.h
Normal file
66
M3KTE_TERM/devicesettingsdialog.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef DEVICESETTINGSDIALOG_H
|
||||
#define DEVICESETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QEvent>
|
||||
|
||||
class BoardIdHasBeenChanged : public QEvent
|
||||
{
|
||||
public:
|
||||
BoardIdHasBeenChanged(const short num, const short newId) : QEvent(QEvent::User) {_BoardNum = num; _BoardNewID = newId;}
|
||||
~BoardIdHasBeenChanged() {}
|
||||
|
||||
short BoardNum() const {return _BoardNum;}
|
||||
short BoardNewID() const {return _BoardNewID;}
|
||||
|
||||
private:
|
||||
short _BoardNum;
|
||||
short _BoardNewID;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class DeviceSettingsDialog;
|
||||
}
|
||||
|
||||
class DeviceSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceSettingsDialog(QWidget *parent = nullptr);
|
||||
~DeviceSettingsDialog();
|
||||
|
||||
unsigned currentBoardTimer(unsigned short _ID);
|
||||
unsigned currentSpeed();
|
||||
unsigned short currentParity();
|
||||
void updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr);
|
||||
signals:
|
||||
void parityChanged();
|
||||
void speedChanged();
|
||||
|
||||
void firstBoardAdrHasBeenChanged();
|
||||
void secondBoardAdrHasBeenChanged();
|
||||
void thirdBoardAdrHasBeenChanged();
|
||||
void fourthBoardAdrHasBeenChanged();
|
||||
|
||||
private slots:
|
||||
void on_buttonApplyChangeTimer_clicked();
|
||||
|
||||
void on_buttonApplyChangeSpeed_clicked();
|
||||
|
||||
void on_buttonApplyChangeParity_clicked();
|
||||
|
||||
void on_buttonApplyChangeAdr_clicked();
|
||||
|
||||
void on_idComboBox_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
unsigned _currentBoardTimers[4];
|
||||
unsigned _currentSpeed;
|
||||
unsigned short _currentParity;
|
||||
unsigned _currentAdrs[4];
|
||||
|
||||
Ui::DeviceSettingsDialog *ui;
|
||||
};
|
||||
|
||||
#endif // DEVICESETTINGSDIALOG_H
|
324
M3KTE_TERM/devicesettingsdialog.ui
Normal file
324
M3KTE_TERM/devicesettingsdialog.ui
Normal file
@ -0,0 +1,324 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DeviceSettingsDialog</class>
|
||||
<widget class="QDialog" name="DeviceSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>243</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Скорость обмена</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonApplyChangeSpeed">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="speedBox">
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2400</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4800</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>9600</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>19200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>31250</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>38400</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>57600</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>115200</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Период опроса плат</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="boardLabel_5">
|
||||
<property name="text">
|
||||
<string>Плата №3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_3">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="boardLabel_1">
|
||||
<property name="text">
|
||||
<string>Плата №1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="buttonApplyChangeTimer">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_2">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="boardLabel_2">
|
||||
<property name="text">
|
||||
<string>Плата №2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_1">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="boardLabel_4">
|
||||
<property name="text">
|
||||
<string>Плата №4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_4">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Сетевой адрес МЗКТЭ</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="idComboBox">
|
||||
<property name="whatsThis">
|
||||
<string>Номер платы</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="adrSpinBox"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="buttonApplyChangeAdr">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Контроль четности</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonApplyChangeParity">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="parityBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Even</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Odd</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DeviceSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DeviceSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
1254
M3KTE_TERM/m3kte.cpp
Normal file
1254
M3KTE_TERM/m3kte.cpp
Normal file
File diff suppressed because it is too large
Load Diff
107
M3KTE_TERM/m3kte.h
Normal file
107
M3KTE_TERM/m3kte.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef M3KTE_H
|
||||
#define M3KTE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QModbusDataUnit>
|
||||
#include <qprogressbar.h>
|
||||
|
||||
#include <QtSerialBus/QModbusDataUnit>
|
||||
#include "writeregistermodel.h"
|
||||
#include "devicesettingsdialog.h"
|
||||
|
||||
#include <QModbusTcpClient>
|
||||
#include <QModbusRtuSerialMaster>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <QErrorMessage>
|
||||
|
||||
#include <QtSerialBus/qtserialbusglobal.h>
|
||||
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
#include <QSerialPort>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class M3KTE; class SettingsDialog;}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class SettingsDialog;
|
||||
class WriteRegisterModel;
|
||||
|
||||
class M3KTE : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
void initActions();
|
||||
QModbusDataUnit readRequest() const;
|
||||
QModbusDataUnit writeRequest() const;
|
||||
void changeTable(int board, int tabletype);
|
||||
void debug();
|
||||
void errorAdrChange();
|
||||
bool event(QEvent* event);
|
||||
bool pingNetworkDevices();
|
||||
void beginScanBoards();
|
||||
void displayResultOfScan(QModbusReply *reply, int boardID);
|
||||
void stepForScanCurrentSettings(QModbusReply *reply);
|
||||
private slots:
|
||||
void onConnectClicked();
|
||||
|
||||
void onReadButtonClicked();
|
||||
void onReadReady();
|
||||
|
||||
void timeForPingIsGone();
|
||||
|
||||
void checkAdrChange();
|
||||
|
||||
void onWriteButtonClicked();
|
||||
void onSelectedBoardChanged(int index);
|
||||
void onWriteTableChanged(int index);
|
||||
|
||||
void onSpeedUpdate();
|
||||
void onParityUpdate();
|
||||
|
||||
|
||||
void firstBoardScan();
|
||||
void secondBoardScan();
|
||||
void thirdBoardScan();
|
||||
void fourthBoardScan();
|
||||
|
||||
void firstBoardReady();
|
||||
void secondBoardReady();
|
||||
void thirdBoardReady();
|
||||
void fourthBoardReady();
|
||||
public:
|
||||
M3KTE(QWidget *parent = nullptr);
|
||||
~M3KTE();
|
||||
|
||||
private:
|
||||
bool timerForPingSignal = false;
|
||||
|
||||
|
||||
|
||||
Ui::M3KTE *ui;
|
||||
//int DeviceOnNetwork[4];
|
||||
QProgressBar *m[320];
|
||||
QModbusReply *lastRequest = nullptr;
|
||||
QModbusClient *modbusDevice = nullptr;
|
||||
DeviceSettingsDialog *m_deviceSettingsDialog = nullptr;
|
||||
SettingsDialog *m_settingsDialog = nullptr;
|
||||
//WriteRegisterModel *writeModel = nullptr;
|
||||
|
||||
struct StatusM3KTE{
|
||||
bool Warnings[4];
|
||||
bool Accidents[4];
|
||||
}statusM3KTE;
|
||||
|
||||
struct BoardModbusRegisters
|
||||
{
|
||||
int adr;
|
||||
int _tmp_adr;
|
||||
WriteRegisterModel *ModbusModelCoil;
|
||||
WriteRegisterModel *ModbusModelHoldingReg;
|
||||
QTimer *boardScanners;
|
||||
}Boards[4];
|
||||
};
|
||||
#endif // M3KTE_H
|
14377
M3KTE_TERM/m3kte.ui
Normal file
14377
M3KTE_TERM/m3kte.ui
Normal file
File diff suppressed because it is too large
Load Diff
62
M3KTE_TERM/settingsdialog.cpp
Normal file
62
M3KTE_TERM/settingsdialog.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->parityCombo->setCurrentIndex(1);
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
ui->baudCombo->setCurrentText(QString::number(m_settings.baud));
|
||||
ui->dataBitsCombo->setCurrentText(QString::number(m_settings.dataBits));
|
||||
ui->stopBitsCombo->setCurrentText(QString::number(m_settings.stopBits));
|
||||
#endif
|
||||
ui->timeoutSpinner->setValue(m_settings.responseTime);
|
||||
ui->retriesSpinner->setValue(m_settings.numberOfRetries);
|
||||
|
||||
connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() {
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
m_settings.portName = ui->portEdit->text();
|
||||
m_settings.parity = ui->parityCombo->currentIndex();
|
||||
if (m_settings.parity > 0)
|
||||
m_settings.parity++;
|
||||
m_settings.baud = ui->baudCombo->currentText().toInt();
|
||||
m_settings.dataBits = ui->dataBitsCombo->currentText().toInt();
|
||||
m_settings.stopBits = ui->stopBitsCombo->currentText().toInt();
|
||||
#endif
|
||||
m_settings.responseTime = ui->timeoutSpinner->value();
|
||||
m_settings.numberOfRetries = ui->retriesSpinner->value();
|
||||
|
||||
hide();
|
||||
});
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
SettingsDialog::Settings SettingsDialog::settings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
int SettingsDialog::UpdateBaud(int baud)
|
||||
{
|
||||
ui->baudCombo->setCurrentText(QString::number(baud, 10));
|
||||
return (m_settings.baud = baud);
|
||||
}
|
||||
|
||||
int SettingsDialog::UpdateParity(int parity)
|
||||
{
|
||||
ui->parityCombo->setCurrentIndex(parity);
|
||||
if(parity>0)
|
||||
{
|
||||
return (m_settings.parity = ++parity);
|
||||
}
|
||||
else {
|
||||
return (m_settings.parity = parity);
|
||||
}
|
||||
}
|
44
M3KTE_TERM/settingsdialog.h
Normal file
44
M3KTE_TERM/settingsdialog.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QtSerialBus/QModbusDataUnit>
|
||||
#include <QtSerialBus/qtserialbusglobal.h>
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
#include <QSerialPort>
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
class SettingsDialog;
|
||||
}
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct Settings {
|
||||
QString portName;
|
||||
int parity = QSerialPort::NoParity;
|
||||
int baud = 31250;
|
||||
int dataBits = QSerialPort::Data8;
|
||||
int stopBits = QSerialPort::OneStop;
|
||||
int responseTime = 1000;
|
||||
int numberOfRetries = 3;
|
||||
};
|
||||
|
||||
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||
~SettingsDialog();
|
||||
|
||||
Settings settings() const;
|
||||
|
||||
int UpdateBaud(int baud);
|
||||
int UpdateParity(int parity);
|
||||
|
||||
|
||||
private:
|
||||
Settings m_settings;
|
||||
Ui::SettingsDialog *ui;
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
284
M3KTE_TERM/settingsdialog.ui
Normal file
284
M3KTE_TERM/settingsdialog.ui
Normal file
@ -0,0 +1,284 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SettingsDialog</class>
|
||||
<widget class="QDialog" name="SettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>311</width>
|
||||
<height>288</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="timeoutSpinner">
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" rowspan="2" colspan="2">
|
||||
<widget class="QSpinBox" name="retriesSpinner">
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="timeoutLabel">
|
||||
<property name="text">
|
||||
<string>Тайм-аут ответа:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>127</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Serial Parameters</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Порт</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="portEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="parityLabel">
|
||||
<property name="text">
|
||||
<string>Чётность</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="parityCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Even</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Odd</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="baudLabel">
|
||||
<property name="text">
|
||||
<string>Скорость</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="baudCombo">
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2400</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4800</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>9600</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>19200</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>31250</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>38400</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>57600</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>115200</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="dataBitsLabel">
|
||||
<property name="text">
|
||||
<string>Биты данных</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="dataBitsCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="stopBitsLabel">
|
||||
<property name="text">
|
||||
<string>Стоп-биты</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="stopBitsCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="retriesLabel">
|
||||
<property name="text">
|
||||
<string>Количество повторов:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QDialogButtonBox" name="AcceptOrRejectButtonBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>AcceptOrRejectButtonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>AcceptOrRejectButtonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
125
M3KTE_TERM/writeregistermodel.cpp
Normal file
125
M3KTE_TERM/writeregistermodel.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include "writeregistermodel.h"
|
||||
|
||||
#include "writeregistermodel.h"
|
||||
|
||||
enum { NumColumn = 0, NameColumn = 1, CoilsColumn = 2, HoldingColumn = 3, ColumnCount = 4};
|
||||
|
||||
WriteRegisterModel::WriteRegisterModel(QObject *parent, int _tmpRC, bool _isHR)
|
||||
: QAbstractTableModel(parent),
|
||||
m_coils(RowCount=_tmpRC, false), m_holdingRegisters(RowCount=_tmpRC, 0u)
|
||||
{
|
||||
isHR=_isHR;
|
||||
}
|
||||
|
||||
int WriteRegisterModel::rowCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return RowCount;
|
||||
}
|
||||
|
||||
int WriteRegisterModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return ColumnCount;
|
||||
}
|
||||
|
||||
QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return QVariant();
|
||||
|
||||
Q_ASSERT(m_coils.count() == RowCount);
|
||||
Q_ASSERT(m_holdingRegisters.count() == RowCount);
|
||||
|
||||
if (index.column() == NumColumn && role == Qt::DisplayRole)
|
||||
return QString::number(index.row());
|
||||
|
||||
if (index.column() == NameColumn && role == Qt::DisplayRole)
|
||||
return QString("ТЭ%1").arg(index.row()%(RowCount/(1+isHR)));
|
||||
|
||||
if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils
|
||||
return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked;
|
||||
|
||||
if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers
|
||||
return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16));
|
||||
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case NumColumn:
|
||||
return QStringLiteral("#Reg");
|
||||
case NameColumn:
|
||||
return QStringLiteral("Fuel Cell");
|
||||
case CoilsColumn:
|
||||
return QStringLiteral("Coils");
|
||||
case HoldingColumn:
|
||||
return QStringLiteral("Holding Registers");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return false;
|
||||
|
||||
Q_ASSERT(m_coils.count() == RowCount);
|
||||
Q_ASSERT(m_holdingRegisters.count() == RowCount);
|
||||
|
||||
if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils
|
||||
auto s = static_cast<Qt::CheckState>(value.toUInt());
|
||||
s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row());
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers
|
||||
bool result = false;
|
||||
quint16 newValue = value.toString().toUShort(&result, 16);
|
||||
if (result)
|
||||
m_holdingRegisters[index.row()] = newValue;
|
||||
|
||||
emit dataChanged(index, index);
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return QAbstractTableModel::flags(index);
|
||||
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
if ((index.row() < m_address) || (index.row() >= (m_address + m_number)))
|
||||
flags &= ~Qt::ItemIsEnabled;
|
||||
|
||||
if (index.column() == CoilsColumn) // coils
|
||||
return flags | Qt::ItemIsUserCheckable;
|
||||
if (index.column() == HoldingColumn) // holding registers
|
||||
return flags | Qt::ItemIsEditable;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void WriteRegisterModel::setStartAddress(int address)
|
||||
{
|
||||
m_address = address;
|
||||
//emit updateViewport();
|
||||
}
|
||||
|
||||
void WriteRegisterModel::setNumberOfValues(const QString &number)
|
||||
{
|
||||
m_number = number.toInt();
|
||||
//emit updateViewport();
|
||||
}
|
38
M3KTE_TERM/writeregistermodel.h
Normal file
38
M3KTE_TERM/writeregistermodel.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef WRITEREGISTERMODEL_H
|
||||
#define WRITEREGISTERMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QBitArray>
|
||||
#include <QObject>
|
||||
|
||||
class WriteRegisterModel : public QAbstractTableModel
|
||||
{
|
||||
private:
|
||||
bool isHR;
|
||||
int RowCount;
|
||||
public:
|
||||
WriteRegisterModel(QObject *parent = nullptr, int _tmpRC = 85, bool _isHR = false);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
public slots:
|
||||
void setStartAddress(int address);
|
||||
void setNumberOfValues(const QString &number);
|
||||
|
||||
signals:
|
||||
void updateViewport();
|
||||
|
||||
public:
|
||||
int m_number = 0;
|
||||
int m_address = 0;
|
||||
QBitArray m_coils;
|
||||
QVector<quint16> m_holdingRegisters;
|
||||
};
|
||||
#endif // WRITEREGISTERMODEL_H
|
15
m3kte.cpp
15
m3kte.cpp
@ -1,15 +0,0 @@
|
||||
#include "m3kte.h"
|
||||
#include "ui_m3kte.h"
|
||||
|
||||
M3KTE::M3KTE(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::M3KTE)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
M3KTE::~M3KTE()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
21
m3kte.h
21
m3kte.h
@ -1,21 +0,0 @@
|
||||
#ifndef M3KTE_H
|
||||
#define M3KTE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class M3KTE; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class M3KTE : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
M3KTE(QWidget *parent = nullptr);
|
||||
~M3KTE();
|
||||
|
||||
private:
|
||||
Ui::M3KTE *ui;
|
||||
};
|
||||
#endif // M3KTE_H
|
22
m3kte.ui
22
m3kte.ui
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>M3KTE</class>
|
||||
<widget class="QMainWindow" name="M3KTE">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>M3KTE</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar"/>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
373
ТЗ/modbus_data.h
Normal file
373
ТЗ/modbus_data.h
Normal file
@ -0,0 +1,373 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus_data.h
|
||||
* @brief Заголовочный файл с описанием даты MODBUS.
|
||||
* @details Данный файл необходимо подключается в rs_message.h. После rs_message.h
|
||||
* подключается к основному проекту.
|
||||
*
|
||||
* @defgroup MODBUS_DATA
|
||||
* @ingroup MODBUS
|
||||
* @brief Modbus data description
|
||||
*
|
||||
*************************************************************************/
|
||||
#include "stdint.h"
|
||||
//--------------DEFINES FOR REGISTERS---------------
|
||||
// DEFINES FOR ARRAYS
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for registers
|
||||
Структура дефайна адресов
|
||||
@verbatim
|
||||
Для массивов регистров:
|
||||
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
|
||||
R_<NAME_ARRAY>_QNT - количество регистров в массиве
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Скорость обмена
|
||||
*/
|
||||
typedef enum //MB_SpeedTypeDef
|
||||
{
|
||||
MB_9600bs = 0x0000, ///< Скорость 9600 б/с
|
||||
MB_14400bs = 0x0001, ///< Скорость 14400 б/с
|
||||
MB_19200bs = 0x0002, ///< Скорость 19200 б/с
|
||||
MB_31250bs = 0x0003, ///< Скорость 31250 б/с
|
||||
MB_38400bs = 0x0004, ///< Скорость 38400 б/с
|
||||
MB_56000bs = 0x0005, ///< Скорость 56000 б/с
|
||||
MB_57600bs = 0x0006, ///< Скорость 57600 б/с
|
||||
MB_115200bs = 0x0007, ///< Скорость 115200 б/с
|
||||
mb16bit = 0x1000, ///< костыль чтобы enum был 16-битный... или забить на enum, пока не определился
|
||||
}MB_SpeedTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Контроль четности
|
||||
*/
|
||||
typedef enum //MB_ParityCtrlTypeDef
|
||||
{
|
||||
NoParityCtrl = 0x0000, ///< контроля нет
|
||||
EvenParityCtrl = 0x0400, ///< четный контроль
|
||||
OddParityCtrl = 0x0600, ///< нечетый контроль
|
||||
}MB_ParityCtrlTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Регистры хранения для уставок параметров МКЗТЭ
|
||||
*/
|
||||
typedef struct //MB_DataHoldRegsTypeDef
|
||||
{
|
||||
|
||||
uint16_t Warning_Setpoints[85]; /*!< @brief Адреса 0-84: Уставки «Предупреждение»
|
||||
@details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Предупреждение».
|
||||
|
||||
Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */
|
||||
|
||||
uint16_t Errors_Setpoints[85]; /*!< @brief Адреса 85-169: Уставки «Авария»
|
||||
@details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Авария».
|
||||
|
||||
Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */
|
||||
|
||||
uint16_t Commands_Mode; /*!< @brief Адрес 170: Уставка «Команды»
|
||||
@details Принимаемые значения:
|
||||
- 0x0000 – стандартная работа
|
||||
- 0x0001 – запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются) */
|
||||
|
||||
uint16_t reserved; ///< Адрес 171 зарезервирован
|
||||
|
||||
uint16_t MZKTE_Network_Adress; /*!< @brief Адрес 172: Уставка «Сетевой адрес МЗКТЭ»
|
||||
@details При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
|
||||
MB_SpeedTypeDef Modbus_Speed:16; /*!< @brief Адрес 173: Уставка «Скорость обмена»
|
||||
@details Принимаемые значения описаны в @ref MB_SpeedTypeDef.
|
||||
|
||||
При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
|
||||
MB_ParityCtrlTypeDef Parity_Control:16; /*!< @brief Адрес 174: Уставка «Команды»
|
||||
@details Принимаемые значения описаны в @ref MB_ParityCtrlTypeDef.
|
||||
|
||||
При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
}MB_DataHoldRegsTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Номер неисправности МЗКТЭ
|
||||
*/
|
||||
typedef enum //MB_MZKTEErrorsTypeDef
|
||||
{
|
||||
No_Err = 0x00, ///< Неисправность отсутствует
|
||||
Err_Digit_5V_Power = 0x01, ///< Неисправность цифрового источника питания +5 В
|
||||
Err_Analog_15V_5V_3V_Power = 0x02, ///< Неисправность аналогового источника питания (±15 В/+5 В/+3,3 В)
|
||||
Err_SCI_5V_Power = 0x03, ///< Неисправность источника питания последовательных интерфейсов микроконтроллера +5 В
|
||||
Err_24V_Power = 0x04, ///< Неисправность источника питания +24 В
|
||||
Program_Err_1 = 0x05, ///< Программная ошибка 1
|
||||
Program_Err_2 = 0x06, ///< Программная ошибка 2
|
||||
Program_Err_3 = 0x07, ///< Программная ошибка 3
|
||||
Program_Err_4 = 0x08, ///< Программная ошибка 4
|
||||
Program_Err_5 = 0x09, ///< Программная ошибка 5
|
||||
Program_Err_6 = 0x0A, ///< Программная ошибка 6
|
||||
Program_Err_7 = 0x0B, ///< Программная ошибка 7
|
||||
Program_Err_8 = 0x0C, ///< Программная ошибка 8
|
||||
}MB_MZKTEErrorsTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Сборный параметр
|
||||
* @details Информация о состоянии МЗКТЭ
|
||||
*/
|
||||
typedef union //MB_MZKTEStatusTypeDef
|
||||
{
|
||||
uint16_t all; ///< Доступ к регистру целиком
|
||||
struct
|
||||
{
|
||||
unsigned TE_ErrActive:1; /*!< @brief Бит [0]: Авария на ТЭ
|
||||
@details Состояния:
|
||||
- 0 - напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария»
|
||||
- 1 - напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария» */
|
||||
|
||||
unsigned TE_WarnActive:1; /*!< @brief Бит [1]: Предупреждения на ТЭ
|
||||
@details Состояния:
|
||||
- 0 - напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение»
|
||||
- 1 - напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение» */
|
||||
|
||||
unsigned Opros_TE:1; /*!< @brief Бит [2]: Разрешение опроса ТЭ
|
||||
@details Состояния:
|
||||
- 0 – опрос ТЭ разрешен
|
||||
- 1 – опрос ТЭ запрещен */
|
||||
|
||||
unsigned MZKTE_ErrStatus:2; /*!< @brief Биты [4:3]: Состояние МЗКТЭ
|
||||
@details Состояния:
|
||||
- 0 - МЗКТЭ функционирует нормально. Идет опрос ТЭ.
|
||||
- 1 - неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции
|
||||
(некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef)
|
||||
- 2 - Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным
|
||||
(ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef) */
|
||||
|
||||
unsigned reserved:3; ///< Биты [7:5] зарезервированны
|
||||
|
||||
MB_MZKTEErrorsTypeDef MZKTE_Error:8; /*!< @brief Биты [15:8]: Номер неисправности МЗКТЭ
|
||||
@details Номера неисправностей описаны в @ref MB_MZKTEErrorsTypeDef */
|
||||
}param; ///< Доступ к регистру по параметрам
|
||||
}MB_MZKTEStatusTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Входные регистры для контроля состояния МЗКТЭ
|
||||
*/
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
|
||||
uint16_t U_TE[85]; /*!< @brief Адреса 0-84: Текущие значения напряжения ТЭ
|
||||
@details Значения передаются умноженными на 1000 (т.е. если Uтэ = 0,625 В, то будет передано число 625) */
|
||||
|
||||
MB_MZKTEStatusTypeDef Status; /*!< @brief Адрес 85: Сборный параметр
|
||||
@details Информация о состоянии МЗКТЭ @ref MB_MZKTEStatusTypeDef */
|
||||
}MB_DataInRegsTypeDef;
|
||||
|
||||
|
||||
// DEFINES FOR REGISTERS ARRAYS
|
||||
#define R_INREG_ADDR 0
|
||||
#define R_INREG_QNT 86
|
||||
|
||||
#define R_HOLDREG_ADDR 0
|
||||
#define R_HOLDREG_QNT 175
|
||||
|
||||
|
||||
// DEFINES FOR REGISTERS LOCAL ADDRESSES
|
||||
//#define R_SET_ERROR(_te_num_) 0
|
||||
|
||||
|
||||
/** MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
//----------------DEFINES FOR COILS-----------------
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_COILS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for coils
|
||||
@verbatim
|
||||
Структура дефайна
|
||||
Для массивов коилов:
|
||||
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
|
||||
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Флаги исключения ТЭ из алгоритма формирования сигналов «Предупреждение» и «Авария»
|
||||
* @details В случае установки нулевого значения конкретной ячейки значение напряжения ТЭ,
|
||||
* связанного с этой ячейкой, не будет учитываться при формировании сигналов «Предупреждение» и «Авария»
|
||||
*/
|
||||
typedef struct //MB_DataCoilsTypeDef
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t TE0_63; ///< Ячейки ТЭ №0-63
|
||||
uint32_t TE64_84:21; ///< Ячейки ТЭ №64-84
|
||||
}all;
|
||||
struct
|
||||
{
|
||||
unsigned TE0_Exclude:1;
|
||||
unsigned TE1_Exclude:1;
|
||||
unsigned TE2_Exclude:1;
|
||||
unsigned TE3_Exclude:1;
|
||||
unsigned TE4_Exclude:1;
|
||||
unsigned TE5_Exclude:1;
|
||||
unsigned TE6_Exclude:1;
|
||||
unsigned TE7_Exclude:1;
|
||||
unsigned TE8_Exclude:1;
|
||||
unsigned TE9_Exclude:1;
|
||||
unsigned TE10_Exclude:1;
|
||||
unsigned TE11_Exclude:1;
|
||||
unsigned TE12_Exclude:1;
|
||||
unsigned TE13_Exclude:1;
|
||||
unsigned TE14_Exclude:1;
|
||||
unsigned TE15_Exclude:1;
|
||||
unsigned TE16_Exclude:1;
|
||||
unsigned TE17_Exclude:1;
|
||||
unsigned TE18_Exclude:1;
|
||||
unsigned TE19_Exclude:1;
|
||||
unsigned TE20_Exclude:1;
|
||||
unsigned TE21_Exclude:1;
|
||||
unsigned TE22_Exclude:1;
|
||||
unsigned TE23_Exclude:1;
|
||||
unsigned TE24_Exclude:1;
|
||||
unsigned TE25_Exclude:1;
|
||||
unsigned TE26_Exclude:1;
|
||||
unsigned TE27_Exclude:1;
|
||||
unsigned TE28_Exclude:1;
|
||||
unsigned TE29_Exclude:1;
|
||||
unsigned TE30_Exclude:1;
|
||||
unsigned TE31_Exclude:1;
|
||||
unsigned TE32_Exclude:1;
|
||||
unsigned TE33_Exclude:1;
|
||||
unsigned TE34_Exclude:1;
|
||||
unsigned TE35_Exclude:1;
|
||||
unsigned TE36_Exclude:1;
|
||||
unsigned TE37_Exclude:1;
|
||||
unsigned TE38_Exclude:1;
|
||||
unsigned TE39_Exclude:1;
|
||||
unsigned TE40_Exclude:1;
|
||||
unsigned TE41_Exclude:1;
|
||||
unsigned TE42_Exclude:1;
|
||||
unsigned TE43_Exclude:1;
|
||||
unsigned TE44_Exclude:1;
|
||||
unsigned TE45_Exclude:1;
|
||||
unsigned TE46_Exclude:1;
|
||||
unsigned TE47_Exclude:1;
|
||||
unsigned TE48_Exclude:1;
|
||||
unsigned TE49_Exclude:1;
|
||||
unsigned TE50_Exclude:1;
|
||||
unsigned TE51_Exclude:1;
|
||||
unsigned TE52_Exclude:1;
|
||||
unsigned TE53_Exclude:1;
|
||||
unsigned TE54_Exclude:1;
|
||||
unsigned TE55_Exclude:1;
|
||||
unsigned TE56_Exclude:1;
|
||||
unsigned TE57_Exclude:1;
|
||||
unsigned TE58_Exclude:1;
|
||||
unsigned TE59_Exclude:1;
|
||||
unsigned TE60_Exclude:1;
|
||||
unsigned TE61_Exclude:1;
|
||||
unsigned TE62_Exclude:1;
|
||||
unsigned TE63_Exclude:1;
|
||||
unsigned TE64_Exclude:1;
|
||||
unsigned TE65_Exclude:1;
|
||||
unsigned TE66_Exclude:1;
|
||||
unsigned TE67_Exclude:1;
|
||||
unsigned TE68_Exclude:1;
|
||||
unsigned TE69_Exclude:1;
|
||||
unsigned TE70_Exclude:1;
|
||||
unsigned TE71_Exclude:1;
|
||||
unsigned TE72_Exclude:1;
|
||||
unsigned TE73_Exclude:1;
|
||||
unsigned TE74_Exclude:1;
|
||||
unsigned TE75_Exclude:1;
|
||||
unsigned TE76_Exclude:1;
|
||||
unsigned TE77_Exclude:1;
|
||||
unsigned TE78_Exclude:1;
|
||||
unsigned TE79_Exclude:1;
|
||||
unsigned TE80_Exclude:1;
|
||||
unsigned TE81_Exclude:1;
|
||||
unsigned TE82_Exclude:1;
|
||||
unsigned TE83_Exclude:1;
|
||||
unsigned TE84_Exclude:1;
|
||||
}bit; ///< Биты для доступа к каждой ячейке ТЭ
|
||||
}Exclude; ///< Юнион для исключения ТЭ
|
||||
}MB_DataCoilsTypeDef;
|
||||
|
||||
// DEFINES FOR COIL ARRAYS
|
||||
#define C_TE_EXCLUDE_ADDR 0
|
||||
#define C_TE_EXCLUDE_QNT 84
|
||||
|
||||
/** MODBUS_DATA_COILS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
//-----------MODBUS DEVICE DATA SETTING-------------
|
||||
// MODBUS DATA STRUCTTURE
|
||||
/**
|
||||
* @brief Структура со всеми регистрами и коилами модбас
|
||||
* @ingroup MODBUS_DATA
|
||||
*/
|
||||
typedef struct // mzkt modbus data
|
||||
{
|
||||
MB_DataInRegsTypeDef InRegs; ///< Modbus input registers @ref MB_DataInRegsTypeDef
|
||||
|
||||
MB_DataCoilsTypeDef Coils; ///< Modbus coils @ref MB_DataCoilsTypeDef
|
||||
|
||||
MB_DataHoldRegsTypeDef HoldRegs; ///< Modbus holding registers @ref MB_DataHoldRegsTypeDef
|
||||
}MB_DataStructureTypeDef;
|
||||
extern MB_DataStructureTypeDef MB_DATA;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
///////////////////////TEMP/OUTDATE/OTHER////////////////////
|
||||
|
||||
//typedef enum //MB_MZKTECommandsTypeDef
|
||||
//{
|
||||
// StandartMode = 0x00, ///< Стандартная работа
|
||||
// Opros_TE_Disable = 0x01, ///< Запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются)
|
||||
//}MB_MZKTECommandsTypeDef;
|
||||
|
||||
///**
|
||||
// * @brief Состояние МЗКТЭ
|
||||
// */
|
||||
//typedef enum //MB_MZKTEErrStatusTypeDef
|
||||
//{
|
||||
// MZKTE_OK = 0x0, ///< МЗКТЭ функционирует нормально. Идет опрос ТЭ.
|
||||
// NonCritical_Err = 0x1, ///< Неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции (некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef).
|
||||
// Critical_Err = 0x2, ///< Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным (ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef)
|
||||
//
|
||||
//}MB_MZKTEErrStatusTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// TE_No_Err = 0x0, ///< Напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария»
|
||||
// TE_Err = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария»
|
||||
//}MB_TEErrActiveTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// TE_No_Warn = 0x0, ///< Напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение»
|
||||
// TE_Warn = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение»
|
||||
//}MB_TEWarnActiveTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// OprosTE_Enable = 0x0, ///< Опрос ТЭ разрешен
|
||||
// OprosTE_Disable = 0x1, ///< Опрос ТЭ запрещен (см. регистр хранения 170)
|
||||
//}MB_OprosTETypeDef;
|
37
ТЗ/неофтз.txt
Normal file
37
ТЗ/неофтз.txt
Normal file
@ -0,0 +1,37 @@
|
||||
По модбасу: нужна терминалка для общения с МЗКТЭ. Вот краткое ТЗ
|
||||
|
||||
Команды:
|
||||
0x01 Read Coils
|
||||
0x03 Read Holding Registers
|
||||
0x04 Read Input Registers
|
||||
0x05 Write Single Coil
|
||||
0x06 Write Single Register
|
||||
0x0F Write Multiple Coils
|
||||
0x10 Write Multiple Registers
|
||||
|
||||
Т.е. обращение будет к следующим типам данных:
|
||||
- Входные регистры (MB_DataInRegsTypeDef),
|
||||
- Регистры хранения (MB_DataHoldRegsTypeDef),
|
||||
- Коилы (MB_DataCoilsTypeDef).
|
||||
|
||||
Там некоторые регистры еще парсяться, поэтому скидываю файл с структурой данных, который я сделал. В скобках указал имя typedef соответствующего типа данных в файле. Можешь его использовать, заодно мб придумаешь че можно улучшить.
|
||||
|
||||
|
||||
По программе:
|
||||
Там идет управление и контроль ТЭ (топливные элементы), которых всего 85 штук. С них снимается задаются две уставки: предупреждение и авария. Коилами можно исключать ТЭ из работы.
|
||||
Также есть пару управляющих настроек и статус-регистр.
|
||||
|
||||
Соответственно можно сделать два окна:
|
||||
- одно небольшое - для статуса МЗКТЭ
|
||||
- второе большое - для ТЭ. Можно сделать 4 вкладки, в каждой 85 ячеек:
|
||||
- Напряжение на ТЭ,
|
||||
- Уставки "Предупреждение",
|
||||
- Уставки "Авария",
|
||||
- Исключения ТЭ
|
||||
|
||||
И можно сделать одно открываемое окно для настроек. Типа по кнопке "Настройки МЗКТЭ". Это для регистров хранения 170-174. И если что их запись должна быть только по команде 0x06 (сингл). Остальные уставки поддерживают запись 0x10 (мультипл).
|
||||
|
||||
Статус МКЗТЭ и Напряжения на ТЭ только считывается (команда 0x04)
|
||||
Уставки "Предупреждение" и "Авария" можно считать и записать всеми способами (0x03, 0x06, 0x10)
|
||||
Настройки МЗКТЭ можно считывать и записать только по одному регистру (0x03, 0x06)
|
||||
Исключения ТЭ можно считывать и записывать всеми способами (0x01, 0x05, 0x0F)
|
BIN
ТЗ/прил.MODBUS.pdf
Normal file
BIN
ТЗ/прил.MODBUS.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user