瀏覽代碼

串口设置界面创建,链接和断开指令添加,下拉框绑定枚举

dev1
永攀 张 2 週之前
父節點
當前提交
c31c511553
共有 8 個檔案被更改,包括 478 行新增13 行删除
  1. +22
    -0
      ModbusDemo/App.xaml.cs
  2. +56
    -0
      ModbusDemo/Extension/EnumBindingSourceExtension.cs
  3. +5
    -4
      ModbusDemo/MainWindow.xaml
  4. +1
    -0
      ModbusDemo/ModbusDemo.csproj
  5. +81
    -0
      ModbusDemo/Uitls/CRCUitl.cs
  6. +146
    -6
      ModbusDemo/VIew/SettingsUC.xaml
  7. +8
    -1
      ModbusDemo/VIewModel/MainWindowViewModel.cs
  8. +159
    -2
      ModbusDemo/VIewModel/SettingsUCViewModel.cs

+ 22
- 0
ModbusDemo/App.xaml.cs 查看文件

@@ -4,6 +4,8 @@ using Prism.DryIoc;
using Prism.Ioc;
using System.Configuration;
using System.Data;
using System.DirectoryServices;
using System.IO.Ports;
using System.Windows;

namespace ModbusDemo
@@ -35,7 +37,27 @@ namespace ModbusDemo
containerRegistry.RegisterForNavigation<RegisterUC, RegisterUCViewModel>();
//将寄存器操作页面和寄存器操作页面的VM结合起来
containerRegistry.RegisterForNavigation<SettingsUC, SettingsUCViewModel>();
//将窗口注册为全局唯一的单例
containerRegistry.RegisterSingleton<SerialPort>();
}
/// <summary>
/// 程序打开默认是设置界面,来设置串口的各个东西
/// </summary>
protected override void OnInitialized()
{
MainWindowViewModel mainWindowViewModel = App.Current.MainWindow.DataContext as MainWindowViewModel;
mainWindowViewModel!.DefultNaigation();
base.OnInitialized();
}



//private SerialPort CreateSerialPort()
//{
// SerialPort serialPort = new SerialPort();
// return serialPort;
//}
}

}

+ 56
- 0
ModbusDemo/Extension/EnumBindingSourceExtension.cs 查看文件

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;

namespace ModbusDemo.Extension
{
class EnumBindingSourceExtension : MarkupExtension
{
private Type _enumType;

public Type EnumType
{
get => _enumType;
set
{
if (value != _enumType)
{
if (value != null)
{
Type enumType = Nullable.GetUnderlyingType(value) ?? value;
if (!enumType.IsEnum)
throw new ArgumentException("Type must be for an Enum.");
}

_enumType = value;
}
}
}

public EnumBindingSourceExtension() { }

public EnumBindingSourceExtension(Type enumType)
{
EnumType = enumType;
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
if (_enumType == null)
throw new InvalidOperationException("The EnumType must be specified.");

var actualEnumType = Nullable.GetUnderlyingType(_enumType) ?? _enumType;
var enumValues = Enum.GetValues(actualEnumType);

if (actualEnumType == _enumType)
return enumValues;

var tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
enumValues.CopyTo(tempArray, 1);
return tempArray;
}
}
}

+ 5
- 4
ModbusDemo/MainWindow.xaml 查看文件

@@ -11,8 +11,9 @@
xmlns:viewmodel="clr-namespace:ModbusDemo.VIewModel"
d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel,IsDesignTimeCreatable=True}"
Title="MainWindow"
Width="1000"
Width="900"
Height="600"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1"></WindowChrome>
@@ -36,10 +37,10 @@
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent">
<md:PackIcon Margin="15,0" HorizontalAlignment="Center" VerticalAlignment="Center" Kind="{Binding Icon}">
<StackPanel Orientation="Horizontal" Background="Transparent" >
<md:PackIcon Margin="15,0" HorizontalAlignment="Center" VerticalAlignment="Center" Kind="{Binding Icon}" FontSize="20">
</md:PackIcon>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding MenuName}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding MenuName}" FontSize="20">
</TextBlock>
</StackPanel>
</DataTemplate>


+ 1
- 0
ModbusDemo/ModbusDemo.csproj 查看文件

@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="MaterialDesignThemes" Version="5.2.1" />
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
<PackageReference Include="System.IO.Ports" Version="9.0.7" />
</ItemGroup>

</Project>

+ 81
- 0
ModbusDemo/Uitls/CRCUitl.cs 查看文件

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModbusDemo.Uitls
{
public static class CRCUitl
{

private static readonly byte[] aucCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
private static readonly byte[] aucCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};

/// <summary>
/// CRC校验
/// </summary>
/// <param name="pucFrame">字节数组</param>
/// <param name="usLen">验证长度</param>
/// <returns>2个字节</returns>
public static byte[] CalculateCRC(byte[] pucFrame, int usLen)
{
int i = 0;
byte[] res = new byte[2] { 0xFF, 0xFF };
ushort iIndex;
while (usLen-- > 0)
{
iIndex = (ushort)(res[0] ^ pucFrame[i++]);
res[0] = (byte)(res[1] ^ aucCRCHi[iIndex]);
res[1] = aucCRCLo[iIndex];
}
return res;
}
}
}

+ 146
- 6
ModbusDemo/VIew/SettingsUC.xaml 查看文件

@@ -5,13 +5,153 @@
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:EnumEx="clr-namespace:ModbusDemo.Extension"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ports="clr-namespace:System.IO.Ports;assembly=System"
xmlns:viewmodel="clr-namespace:ModbusDemo.VIewModel"
d:DataContext="{d:DesignInstance Type=viewmodel:SettingsUCViewModel,
IsDesignTimeCreatable=True}"
d:DesignHeight="450"
d:DesignWidth="800"
d:Background="White"
mc:Ignorable="d">
<StackPanel>
<TextBlock Text="Settings" FontSize="30">
</TextBlock>
<TextBlock Text="Settings" FontSize="30">
</TextBlock>
</StackPanel>
<UserControl.Resources>
<EnumEx:EnumBindingSource x:Key="enumParity" EnumType="{x:Type ports:Parity}">
</EnumEx:EnumBindingSource>
<EnumEx:EnumBindingSource x:Key="enumStopBits" EnumType="{x:Type ports:StopBits}">
</EnumEx:EnumBindingSource>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition>
</RowDefinition>
<RowDefinition>
</RowDefinition>
<RowDefinition>
</RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- 这是设置串口的选择 -->
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="20,0,0,5" Text="串口选择">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
SelectedItem="{Binding PortName}">
<ComboBoxItem Content="COM1" />
<ComboBoxItem Content="COM2" />
<ComboBoxItem Content="COM3" />
<ComboBoxItem Content="COM4" />
</ComboBox>
</StackPanel>
<!-- 设置波特率 -->
<StackPanel Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="20,0,0,5" Text="波特率">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
SelectedItem="{Binding BaudRate}">
<ComboBoxItem Content="4800" />
<ComboBoxItem Content="9600" />
<ComboBoxItem Content="19200" />
<ComboBoxItem Content="38400" />
<ComboBoxItem Content="5600" />
<ComboBoxItem Content="57600" />
<ComboBoxItem Content="115200" />
<ComboBoxItem Content="187500" />
</ComboBox>
</StackPanel>
<!-- 这是设置校验位的选择 -->
<StackPanel Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="10,0,0,5" Text="校验位选择">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource enumParity}}"
SelectedItem="{Binding Parity}">
</ComboBox>
</StackPanel>
<!-- 这是设置停止位的选择 -->
<StackPanel Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="10,0,0,5" Text="停止位选择">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource enumStopBits}}"
SelectedItem="{Binding StopBits}">
</ComboBox>
</StackPanel>

<!-- 这是设置数据位的选择 -->
<StackPanel Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="10,0,0,5" Text="数据位选择">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
SelectedItem="{Binding DataBits}">
<ComboBoxItem Content="7">
</ComboBoxItem>
<ComboBoxItem Content="8">
</ComboBoxItem>
</ComboBox>
</StackPanel>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<Button
Width="80"
Height="30"
materialDesign:ButtonAssist.CornerRadius="15"
Style="{StaticResource MaterialDesignRaisedDarkButton}"
Content="链接"
Command="{Binding ConnectionCmm}">
</Button>
<Button
Grid.Column="1"
Width="80"
Height="30"
materialDesign:ButtonAssist.CornerRadius="15"
Style="{StaticResource MaterialDesignRaisedDarkButton}"
Content="断开"
Command="{Binding ConnectionCmm}">
</Button>
</Grid>
</Grid>
</UserControl>

+ 8
- 1
ModbusDemo/VIewModel/MainWindowViewModel.cs 查看文件

@@ -50,7 +50,9 @@ namespace ModbusDemo.VIewModel
{
_regionManager.Regions["ModbusRegion"].RequestNavigate(info.ViewName);
}

/// <summary>
/// 初始化左下拉框
/// </summary>
private void CreateLeftMenus()
{
LeftMenusList = new();
@@ -58,5 +60,10 @@ namespace ModbusDemo.VIewModel
LeftMenusList.Add(new MenusInfo() { Icon = "BlurCircular", MenuName = "寄存器操作", ViewName = "RegisterUC" });
LeftMenusList.Add(new MenusInfo() { Icon = "Settings", MenuName = "串口设置", ViewName = "SettingsUC" });
}

public void DefultNaigation()
{
_regionManager.Regions["ModbusRegion"].RequestNavigate("SettingsUC");
}
}
}

+ 159
- 2
ModbusDemo/VIewModel/SettingsUCViewModel.cs 查看文件

@@ -1,13 +1,170 @@
using Prism.Mvvm;
using ModbusDemo.Uitls;
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;

namespace ModbusDemo.VIewModel
{
class SettingsUCViewModel:BindableBase
class SettingsUCViewModel : BindableBase
{
public DelegateCommand DisConnectionCmm { get; set; }
//链接窗口的命令
public DelegateCommand ConnectionCmm { get; set; }

//获取串口
private SerialPort _serialPort;
//设置串口名字
private string _portName = "COM1";

public string PortName
{
get { return _portName; }
set
{
_portName = value;
RaisePropertyChanged();
}
}

//设置波特率
private string _baudRate = "19200";

public string BaudRate
{
get { return _baudRate; }
set
{
_baudRate = value;
RaisePropertyChanged();
}
}

//设置数据位
private string _dataBits = "8";

public string DataBits
{
get { return _dataBits; }
set
{
_dataBits = value;

RaisePropertyChanged();
}
}
//设置校验位
private Parity _parity = Parity.Even;

public Parity Parity
{
get { return _parity; }
set
{
_parity = value;
RaisePropertyChanged();
}
}

//设置停止位
private StopBits _stopBits = StopBits.One;

public StopBits StopBits
{
get { return _stopBits; }
set
{
_stopBits = value;
RaisePropertyChanged();
}
}

public SettingsUCViewModel()
{
}
/// <summary>
/// 从容器中获取创建的窗口
/// </summary>
/// <param name="serialPort"></param>
public SettingsUCViewModel(SerialPort serialPort)
{
_serialPort = serialPort;
ConnectionCmm = new DelegateCommand(Connection);
DisConnectionCmm = new DelegateCommand(DisConnection);
}

private void DisConnection()
{
if (_serialPort.IsOpen)
{
_serialPort.Close();
}
}

/// <summary>
/// 串口参数设置
/// </summary>
private void Connection()
{
//todo,做数据的判空处理
if (!_serialPort.IsOpen)
{
_serialPort.PortName = GetComboBoxItemValue(this.PortName);
_serialPort.BaudRate = int.Parse(GetComboBoxItemValue(this.BaudRate));
_serialPort.Parity = this.Parity;
_serialPort.StopBits = this.StopBits;
_serialPort.DataBits = int.Parse(GetComboBoxItemValue(this.DataBits));
_serialPort.Open();
}




List<byte> bytes = new List<byte>();
bytes.Add(0x01);
bytes.Add(0x05);


bytes.Add(BitConverter.GetBytes(301)[1]);
bytes.Add(BitConverter.GetBytes(301)[0]);


bytes.Add(0xFF);
bytes.Add(0x00);

byte[] bytes1 = CRCUitl.CalculateCRC(bytes.ToArray(), bytes.Count);

bytes.Add(bytes1[0]);
bytes.Add(bytes1[1]);
byte[] bytes2 = bytes.ToArray();
System.Threading.Thread.Sleep(200); // 等待200毫秒

byte[] response = new byte[_serialPort.BytesToRead];
//int bytesRead = serialPort.Read(response, 0, response.Length);

//string hexResponse = BitConverter.ToString(response, 0, bytesRead);
_serialPort.Write(bytes2, 0, bytes2.Length);
}
/// <summary>
/// 处理下拉框的选择信息
/// </summary>
/// <param name="ComboBoxItem"></param>
/// <returns></returns>
private string GetComboBoxItemValue(string ComboBoxItem)
{

string displayText = ComboBoxItem.ToString();
string cleanText = displayText.Replace("System.Windows.Controls.ComboBoxItem: ", "");
return cleanText;
}

}
}

Loading…
取消
儲存