这篇“基于WPF怎么编写一个串口转UDP工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于WPF怎么编写一个串口转UDP工具”文章吧。
尽管希望做一个转发工具,但如果自身不会发送的话,那还得再用其他软件进行测试,所以这个转发工具,理应具备串口和UDP协议的全部功能,这一点也要在界面上体现出来。
新建一个WPF项目,名字是portUDP,然后开始布局,结果如下
其中,串口设置中包含波特率、数据位、停止位和奇偶校验等信息,由于不常更换,所以隐藏起来。
串口只需要一个,但UDP通信需要设置本机和目标的IP地址与端口。自动转发单选框选中后,会自动将接收到的串口数据转给UDP,并且UDP收到的数据也会转给串口。
窗口尺寸为320 × 640 320\times640320×640,外部采用一个DockPanel,并对常用控件进行基本的外观设置
<DockPanel.Resources>
<Style TargetType="TextBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="2"/>
</Style>
</DockPanel.Resources>
左侧控制面板被写在一个StackPanel中,最上面是一个Expander,里面包含串口设置的相关信息
<Expander Header="串口设置">
<UniformGrid Columns="2" Visibility="Visible">
<TextBlock Text="波特率"/>
<ComboBox x:Name="cbBaud"/>
<TextBlock Text="数据位"/>
<ComboBox x:Name="cbDataBit"/>
<TextBlock Text="停止位"/>
<ComboBox x:Name="cbStopBit"/>
<TextBlock Text="校验位"/>
<ComboBox x:Name="cbParity"/>
</UniformGrid>
</Expander>
然后是一个GroupBox,用于进行基本设置,其中两个按钮需要在连接后更改内容,所以设了个名字。
<UniformGrid Columns="2">
<ComboBox x:Name="cbPorts" Margin="2"/>
<Button x:Name="btnPort" Content="连接串口"/>
<TextBox x:Name="txtSrcIP" Text="127.0.0.1"/>
<TextBox x:Name="txtSrcPort" Text="91"/>
<TextBox x:Name="txtDstIP" Text="127.0.0.1"/>
<TextBox x:Name="txtDstPort" Text="91"/>
<CheckBox Content="自动转发" IsChecked="True"/>
<Button x:Name="btnUDP" Content="创建服务"/>
</UniformGrid>
最后是发送文本框与发送按钮等,内容如下
<TextBox x:Name="txtSend" TextWrapping="Wrap" Height="70"/>
<UniformGrid Columns="3">
<CheckBox Content="Hex" IsChecked="False"/>
<Button Content="串口发送"/>
<Button Content="UDP发送"/>
<CheckBox Content="时间"/>
<Button Content="清空日志"/>
<Button Content="保存日志"/>
</UniformGrid>
左侧控制界面布局完成后,是右侧的接收区域,内容如下
<GroupBox Header="日志信息">
<TextBox x:Name="txtInfo" Height="270"/>
</GroupBox>
由于.Net6.0不内置串口库,所以需要额外下载,点击菜单栏工具->NuGet包管理器->管理解决方案的NuGet包,点击浏览选项卡,搜索Ports,选择System.IO.Ports,安装。
在对用户界面进行最简单的布局后,可以在C#代码中,对一些ComboBox做进一步的设置。
public void initComContent()
{
// 串口号
cbPorts.ItemsSource = SerialPort.GetPortNames();
cbPorts.SelectedIndex = 0;
// 波特率
cbBaud.ItemsSource = new int[] { 9600, 19200, 38400, 115200 };
cbBaud.SelectedIndex = 3;
// 数据位
cbDataBit.ItemsSource = Enumerable.Range(1, 8);
cbDataBit.SelectedIndex = 7;
// 校验位
cbParity.ItemsSource = Enum.GetNames(typeof(Parity));
cbParity.SelectedIndex = 0;
//停止位
cbStopBit.ItemsSource = Enum.GetNames(typeof(StopBits));
cbStopBit.SelectedIndex = 1;
}
这样,在打开软件之后,串口设置如下
接下来设置串口,在xml编辑界面,将btnPort后面添加Click="btnPort_Click"后,按下F12,IDE会自动创建对应的函数。
<Button x:Name="btnPort" Content="连接串口" Click="btnPort_Click"/>
在写串口开关按钮的控制指令之前,先新建一个全局的串口对象,然后写btnPort_Click内容
SerialPort sp;
private void btnPort_Click(object sender, RoutedEventArgs e)
{
if (btnPort.Content.ToString() == "打开串口")
{
string name = cbPorts.SelectedItem.ToString();
try
{
sp = new SerialPort(name,
(int)cbBaud.SelectedItem,
(Parity)cbParity.SelectedIndex,
(int)cbDataBit.SelectedItem,
(StopBits)cbStopBit.SelectedIndex);
sp.Open();
sp.DataReceived += Sp_DataReceived;
txtInfo.AppendText($"串口{name}打开成功");
}
catch(Exception ex)
{
txtInfo.AppendText($"串口{name}打开失败,原因是{ex}");
}
}
else
{
try
{
sp.Close();
initComContent();
}
catch (Exception ex)
{
txtInfo.AppendText($"串口关闭失败,原因是{ex}");
}
}
btnPort.Content = sp.IsOpen ? "关闭串口" : "打开串口";
}
其中sp.DataReceived += Sp_DataReceived;新增一个委托,用于规范串口接收到数据后的行为。
和串口设置相同,UDP也需要新建用于UDP通信的全局变量,包括本机节点、目标节点以及UDP服务。
UdpClient udp;
IPEndPoint ptSrc;
IPEndPoint ptDst;
然后设置创建服务按钮后,其逻辑与串口是相似的,都是在创建或关闭服务时,用try-catch语句以找到错误。
private void btnUDP_Click(object sender, RoutedEventArgs e)
{
if (btnUDP.Content.ToString() == "创建服务")
{
try
{
ptSrc = new IPEndPoint(IPAddress.Parse(txtSrcIP.Text), int.Parse(txtSrcPort.Text));
ptDst = new IPEndPoint(IPAddress.Parse(txtDstIP.Text), int.Parse(txtDstPort.Text));
udp = new UdpClient(ptSrc);
txtInfo.AppendText("成功创建服务");
btnUDP.Content = "关闭服务";
}catch(Exception ex)
{
txtInfo.AppendText($"服务创建失败,原因为{ex}\n");
}
}
else
{
try
{
udp.Close();
btnUDP.Content = "创建服务";
}
catch(Exception ex)
{
txtInfo.AppendText($"服务关闭失败,原因为{ex}");
}
}
}
首先是串口发送,在xaml文件中,为串口发送按钮挂载一个Click动作,其内容即为串口发送功能
<Button Content="串口发送" Click="btnPortSend_Click"/>
private void btnPortSend_Click(object sender, RoutedEventArgs e)
{
var data = Encoding.UTF8.GetBytes(txtSend.Text);
txtInfo.AppendText($"串口发送{txtSend.Text}\n");
sp.Write(data, 0, data.Length);
}
然后是UDP发送,其改装过程也大同小异
<Button Content="UDP发送" Click="btnUDPSend_Click"/>
private void btnUDPSend_Click(object sender, RoutedEventArgs e)
{
var data = Encoding.UTF8.GetBytes(txtSend.Text);
txtInfo.AppendText($"UDP发送{txtSend.Text}\n");
udp.Send(data, data.Length, ptDst); //将内容发给ptDst
}
转发是本软件的核心功能,但其前提是接收到数据。所以,先来充实创建串口时就已经提到的Sp_DataReceived函数
private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[sp.BytesToRead];
sp.Read(data, 0, data.Length);//从串口读取数据
Dispatcher.Invoke(() => spReceived(data));
}
private void spReceived(byte[] data)
{
string info = Encoding.UTF8.GetString(data);
txtInfo.AppendText("串口接收数据:{info}");
if ((bool)chkTransmit.IsChecked)
{
try
{
udp.Send(data, data.Length, ptDst); //将内容发给ptDst
txtInfo.AppendText($"UDP转发:{info}");
}
catch (Exception ex)
{
txtInfo.AppendText($"UDP转发失败,原因为{ex}\nd");
}
}
}
然后创建UPD接收和转发函数
private void udpReceiving(CancellationToken token)
{
while (! token.IsCancellationRequested)
{
var data = udp.Receive(ref ptDst);
Dispatcher.Invoke(() => udpReceived(data));
}
}
private void udpReceived(byte[] data)
{
string info = Encoding.UTF8.GetString(data);
txtInfo.AppendText("UDP接收数据:{info}");
if ((bool)chkTransmit.IsChecked)
{
try
{
sp.Write(data, 0, data.Length);
txtInfo.AppendText($"串口转发{info}\n");
}
catch (Exception ex)
{
txtInfo.AppendText($"串口转发失败,原因为{ex}");
}
}
}
其中,udpReceiving里面是一个死循环,表示一直等待UDP信息的到来,这个函数作为一个Task的创建时机,自然是在UDP服务创建之时,
//...
txtInfo.AppendText("成功创建服务");
//这是一个全局变量
cts = new CancellationTokenSource();
Task.Run(() => udpReceiving(cts.Token), cts.Token);
至此,一个串口-UDP转发工具便算完成了,尽管界面上还有几个功能没有实现,比如Hex以及时间的单选框等,但这些均为锦上添花。
下面做一下基础的测试,效果如下
以上就是关于“基于WPF怎么编写一个串口转UDP工具”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://blog.csdn.net/m0_37816922/article/details/129858681