中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于WPF怎么編寫一個串口轉UDP工具

發布時間:2023-05-09 16:08:48 來源:億速云 閱讀:133 作者:iii 欄目:開發技術

這篇“基于WPF怎么編寫一個串口轉UDP工具”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“基于WPF怎么編寫一個串口轉UDP工具”文章吧。

框架準備

盡管希望做一個轉發工具,但如果自身不會發送的話,那還得再用其他軟件進行測試,所以這個轉發工具,理應具備串口和UDP協議的全部功能,這一點也要在界面上體現出來。

新建一個WPF項目,名字是portUDP,然后開始布局,結果如下

基于WPF怎么編寫一個串口轉UDP工具

其中,串口設置中包含波特率、數據位、停止位和奇偶校驗等信息,由于不常更換,所以隱藏起來。

串口只需要一個,但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;
}

這樣,在打開軟件之后,串口設置如下

基于WPF怎么編寫一個串口轉UDP工具

串口設置

接下來設置串口,在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通信的全局變量,包括本機節點、目標節點以及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工具

以上就是關于“基于WPF怎么編寫一個串口轉UDP工具”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

萍乡市| 眉山市| 祁门县| 泽州县| 广昌县| 凌云县| 凤凰县| 夏邑县| 垣曲县| 阜新| 观塘区| 措勤县| 名山县| 五莲县| 富裕县| 仪陇县| 晋城| 呼玛县| 华宁县| 铁岭市| 射洪县| 阿拉尔市| 十堰市| 华蓥市| 客服| 寿阳县| 泽库县| 肇源县| 阜新市| 金坛市| 尚志市| 邢台县| 曲水县| 从江县| 宜丰县| 福州市| 静宁县| 南宁市| 新闻| 临沂市| 镇安县|