diff --git a/ModbusDemo/Device/IModbusRTU.cs b/ModbusDemo/Device/IModbusRTU.cs
index 847e908..250c8d5 100644
--- a/ModbusDemo/Device/IModbusRTU.cs
+++ b/ModbusDemo/Device/IModbusRTU.cs
@@ -13,5 +13,7 @@ namespace ModbusDemo.Device
public void WriteCoil(byte slaveAddress, ushort startAddress, bool[] data);
+ public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
+
}
}
diff --git a/ModbusDemo/Device/ModbusRTU.cs b/ModbusDemo/Device/ModbusRTU.cs
index 0c3fae7..aee8904 100644
--- a/ModbusDemo/Device/ModbusRTU.cs
+++ b/ModbusDemo/Device/ModbusRTU.cs
@@ -58,7 +58,7 @@ namespace ModbusDemo.Device
Thread.Sleep(300);
byte[] response = new byte[_serialPort.BytesToRead];
_serialPort.Read(response, 0, _serialPort.BytesToRead);
- return Parseresponse(response,numberOfPoints);
+ return ParseCoilresponse(response,numberOfPoints);
}
@@ -66,7 +66,7 @@ namespace ModbusDemo.Device
}
- public bool[] Parseresponse(byte[] response, ushort numberOfPoints)
+ public bool[] ParseCoilresponse(byte[] response, ushort numberOfPoints)
{
//判断发送回来的数据是否正确
CheckData.CheckResponse(response);
@@ -107,7 +107,12 @@ namespace ModbusDemo.Device
}
return ultimately;
}
-
+ ///
+ /// 写入多个线圈操作
+ ///
+ /// 从站地址
+ /// 起始地址
+ /// 写入的数据
public void WriteCoil(byte slaveAddress, ushort startAddress, bool[] data)
{
List sendByteList = new List();
@@ -172,5 +177,66 @@ namespace ModbusDemo.Device
}
+
+ public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
+ {
+ if (!_serialPort.IsOpen)
+ {
+ MessageBox.Show("串口没有链接,请先链接");
+ return null;
+ }
+ List sendByteList = new List();
+ //设置从站地址
+ sendByteList.Add(slaveAddress);
+ //设置功能码
+ sendByteList.Add(0x03);
+ //设置起始地址的高位和低位
+ sendByteList.Add(BitConverter.GetBytes(startAddress)[1]);
+ sendByteList.Add(BitConverter.GetBytes(startAddress)[0]);
+ //设置读取几个线圈的高位和低位
+ sendByteList.Add(BitConverter.GetBytes(numberOfPoints)[1]);
+ sendByteList.Add(BitConverter.GetBytes(numberOfPoints)[0]);
+ //获取CRC校验码
+ byte[] getCRC = sendByteList.ToArray();
+ byte[] resultCRC = CRCUitl.CalculateCRC(getCRC, getCRC.Length);
+ sendByteList.Add(resultCRC[0]);
+ sendByteList.Add(resultCRC[1]);
+
+ byte[] sendByte = sendByteList.ToArray();
+ if (_serialPort.IsOpen)
+ {
+ // 清空接收缓冲区(避免残留数据干扰)
+ _serialPort.DiscardInBuffer();
+
+ _serialPort.Write(sendByte, 0, sendByte.Length);
+ Thread.Sleep(300);
+ byte[] response = new byte[_serialPort.BytesToRead];
+ _serialPort.Read(response, 0, _serialPort.BytesToRead);
+ return ParseRegistersresponse(response, numberOfPoints);
+ }
+
+ return null;
+ }
+ public ushort[] ParseRegistersresponse(byte[] response, ushort numberOfPoints)
+ {
+ //判断发送回来的数据是否正确
+ CheckData.CheckResponse(response);
+
+ if (!CRCUitl.ValidateCRC(response))
+ {
+ MessageBox.Show("0x14:CRC校验错误");
+ return null;
+ }
+
+ ushort[] registers = new ushort[numberOfPoints];
+ for (int i = 0; i < numberOfPoints; i++)
+ {
+ int pos = 3 + i * 2;
+ // 大端序转换 (高位在前)
+ registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]);
+ }
+
+ return registers;
+ }
}
}
diff --git a/ModbusDemo/Extension/EnumBindingSourceExtension.cs b/ModbusDemo/Extension/EnumBindingSourceExtension.cs
index 027db05..29320aa 100644
--- a/ModbusDemo/Extension/EnumBindingSourceExtension.cs
+++ b/ModbusDemo/Extension/EnumBindingSourceExtension.cs
@@ -7,6 +7,9 @@ using System.Windows.Markup;
namespace ModbusDemo.Extension
{
+ ///
+ /// 此处代码是复制粘贴,用来让枚举类型绑定到下拉框上
+ ///
class EnumBindingSourceExtension : MarkupExtension
{
private Type _enumType;
diff --git a/ModbusDemo/MainWindow.xaml b/ModbusDemo/MainWindow.xaml
index e3fd029..f38d325 100644
--- a/ModbusDemo/MainWindow.xaml
+++ b/ModbusDemo/MainWindow.xaml
@@ -7,16 +7,18 @@
xmlns:local="clr-namespace:ModbusDemo"
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
- xmlns:prism="http://prismlibrary.com/"
- xmlns:viewmodel="clr-namespace:ModbusDemo.VIewModel"
- d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel,IsDesignTimeCreatable=True}"
+ xmlns:prism="http://prismlibrary.com/"
+ xmlns:viewmodel="clr-namespace:ModbusDemo.VIewModel"
Title="MainWindow"
Width="900"
Height="600"
+ d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel,
+ IsDesignTimeCreatable=True}"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
-
+
+
@@ -37,8 +39,13 @@
-
-
+
+
diff --git a/ModbusDemo/VIew/CoilUC.xaml b/ModbusDemo/VIew/CoilUC.xaml
index 3ac4a84..db83084 100644
--- a/ModbusDemo/VIew/CoilUC.xaml
+++ b/ModbusDemo/VIew/CoilUC.xaml
@@ -13,6 +13,12 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
+
+
+
@@ -45,6 +51,10 @@
+
+
+
+
@@ -66,11 +76,11 @@
-
-
-
-
-
+
+
+
+
+
+
@@ -115,7 +126,12 @@
-
+
diff --git a/ModbusDemo/VIew/RegisterUC.xaml b/ModbusDemo/VIew/RegisterUC.xaml
index b0f47d4..adaf8cb 100644
--- a/ModbusDemo/VIew/RegisterUC.xaml
+++ b/ModbusDemo/VIew/RegisterUC.xaml
@@ -5,11 +5,147 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ModbusDemo.VIew"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:viewmodel="clr-namespace:ModbusDemo.VIewModel"
+ d:DataContext="{d:DesignInstance Type=viewmodel:RegisterUCViewModel,
+ IsDesignTimeCreatable=True}"
d:DesignHeight="450"
+ d:Background="White"
d:DesignWidth="800"
mc:Ignorable="d">
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ModbusDemo/VIewModel/RegisterUCViewModel.cs b/ModbusDemo/VIewModel/RegisterUCViewModel.cs
index 2a5747f..dbf94e9 100644
--- a/ModbusDemo/VIewModel/RegisterUCViewModel.cs
+++ b/ModbusDemo/VIewModel/RegisterUCViewModel.cs
@@ -1,13 +1,198 @@
-using Prism.Mvvm;
+using ModbusDemo.Device;
+using Prism.Commands;
+using Prism.Mvvm;
using System;
using System.Collections.Generic;
+using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
namespace ModbusDemo.VIewModel
{
class RegisterUCViewModel:BindableBase
{
+
+ //获取读线圈的类
+ private IModbusRTU _modbusRTU;
+ //定义读线圈的命令
+ public DelegateCommand ReadRegisterCmm { get; set; }
+ //定义写线圈操作
+ public DelegateCommand WriteRegisterCmm { get; set; }
+ //获取当前使用的串口
+ private SerialPort _serialPort;
+ //显示当前链接串口的信息
+ public string SerialPortInfo
+ {
+ get
+ {
+ return "当前链接的状态:" + "串口号:" + _serialPort.PortName + ",波特率:" + _serialPort.BaudRate
+ + ",数据位:" + _serialPort.DataBits + ",校验位:" + _serialPort.Parity + ",停止位:" + _serialPort.StopBits;
+ }
+
+ }
+ #region 读取定义
+
+ //读取的从站id
+ private string _slaveAddress;
+
+ public string SlaveAddress
+ {
+ get { return _slaveAddress; }
+ set
+ {
+ _slaveAddress = value;
+ RaisePropertyChanged();
+ }
+ }
+ //读取的起始地址
+ private string _startAddress;
+
+
+ public string StartAddress
+ {
+ get { return _startAddress; }
+ set
+ {
+ _startAddress = value;
+ RaisePropertyChanged();
+ }
+ }
+ //读取的位数
+ private string _numberOfPoints;
+
+
+ public string NumberOfPoints
+ {
+ get { return _numberOfPoints; }
+ set
+ {
+ _numberOfPoints = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ private string _readResult;
+
+ //读取的结果
+ public string ReadResult
+ {
+ get { return _readResult; }
+ set
+ {
+ _readResult = value;
+ RaisePropertyChanged();
+ }
+ }
+ #endregion
+
+ #region 写入定义
+
+ //写入的从站id
+ private string _writeslaveAddress;
+
+ public string WriteSlaveAddress
+ {
+ get { return _writeslaveAddress; }
+ set
+ {
+ _writeslaveAddress = value;
+ RaisePropertyChanged();
+ }
+ }
+ //写入的起始地址
+ private string _writestartAddress;
+
+
+ public string WriteStartAddress
+ {
+ get { return _writestartAddress; }
+ set
+ {
+ _writestartAddress = value;
+ RaisePropertyChanged();
+ }
+ }
+ //写入的数据
+ private string _writeData;
+
+
+ public string WriteData
+ {
+ get { return _writeData; }
+ set
+ {
+ _writeData = value;
+ RaisePropertyChanged();
+ }
+ }
+
+
+ #endregion
+
+ public RegisterUCViewModel()
+ {
+
+ }
+ public RegisterUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU)
+ {
+ _serialPort = serialPort;
+ ReadRegisterCmm = new DelegateCommand(ReadRegister);
+ _modbusRTU = modbusRTU;
+ WriteRegisterCmm = new DelegateCommand(WriteRegister);
+ }
+
+
+
+
+ ///
+ /// 线圈读取操作
+ ///
+ private void ReadRegister()
+ {
+ try
+ {
+ ushort[] result = _modbusRTU.ReadRegisters(byte.Parse(SlaveAddress),
+ ushort.Parse(StartAddress),
+ ushort.Parse(NumberOfPoints));
+ if (result != null)
+ {
+ string temp = "";
+ foreach (var item in result)
+ {
+ temp += item;
+ temp += " ";
+ }
+ ReadResult = temp;
+ }
+ }
+ catch (Exception)
+ {
+
+ MessageBox.Show("参数配置错误");
+ }
+
+ }
+ private void WriteRegister()
+ {
+ //去除字符串中的空格
+ WriteData = WriteData.Replace(" ", "");
+ //转换为布尔数组
+ bool[] data = WriteData.Select(m => m == '1').ToArray();
+
+ try
+ {
+ _modbusRTU.WriteCoil(byte.Parse(WriteSlaveAddress),
+ ushort.Parse(WriteStartAddress),
+ data);
+ }
+ catch (Exception)
+ {
+
+ MessageBox.Show("信息配置错误");
+ }
+
+ }
}
}
diff --git a/ModbusDemo/VIewModel/SettingsUCViewModel.cs b/ModbusDemo/VIewModel/SettingsUCViewModel.cs
index 79beda4..1d3cca7 100644
--- a/ModbusDemo/VIewModel/SettingsUCViewModel.cs
+++ b/ModbusDemo/VIewModel/SettingsUCViewModel.cs
@@ -1,6 +1,7 @@
using ModbusDemo.Uitls;
using Prism.Commands;
using Prism.Mvvm;
+using Prism.Regions;
using System;
using System.Collections.Generic;
using System.IO.Ports;
@@ -14,6 +15,9 @@ namespace ModbusDemo.VIewModel
class SettingsUCViewModel : BindableBase
{
+ //控制页面跳转
+ private readonly IRegionManager _regionManager;
+ //断开连接的命令
public DelegateCommand DisConnectionCmm { get; set; }
//链接窗口的命令
public DelegateCommand ConnectionCmm { get; set; }
@@ -93,11 +97,12 @@ namespace ModbusDemo.VIewModel
/// 从容器中获取创建的窗口
///
///
- public SettingsUCViewModel(SerialPort serialPort)
+ public SettingsUCViewModel(SerialPort serialPort, IRegionManager regionManager)
{
_serialPort = serialPort;
ConnectionCmm = new DelegateCommand(Connection);
DisConnectionCmm = new DelegateCommand(DisConnection);
+ _regionManager = regionManager;
}
private void DisConnection()
@@ -127,6 +132,8 @@ namespace ModbusDemo.VIewModel
_serialPort.DataBits = int.Parse(GetComboBoxItemValue(this.DataBits));
_serialPort.Open();
MessageBox.Show("串口链接成功");
+ _regionManager.Regions["ModbusRegion"].RequestNavigate("CoilUC");
+
}
catch (Exception)
{