之前寫過串口通信,不過是winform的。
c#使用串口進行通信_c# 串口通信_故里2130的博客-CSDN博客
今天說一下,.net6中wpf的串口通信和USB通信,在工控行業(yè)中,這2種的方式非常多,還有網(wǎng)口通信,它們都是用來和硬件打交道的,進行交互信息。
一、串口通信
1.安裝System.IO.Ports
2.基本上代碼都是一樣的,xaml界面
<Window x:Class="WPFPortsUSB.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFPortsUSB"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox Name="txtPort"/>
<Button Name="btnLink" Height="25" Content="連接" Click="btnLink_Click"/>
<TextBox Name="txtSend"/>
<Button Name="btnSend" Height="25" Content="發(fā)送" Click="btnSend_Click"/>
<TextBlock Text="接收的數(shù)據(jù)"/>
<TextBox Name="txtReceive"/>
</StackPanel>
</Window>
3.cs代碼
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFPortsUSB
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
SerialPort serialPort = new SerialPort();
public MainWindow()
{
InitializeComponent();
}
private void btnLink_Click(object sender, RoutedEventArgs e)
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
if (ports.Length == 0)
{
MessageBox.Show("本機沒有串口!");
}
serialPort.PortName = ports[Convert.ToInt16(txtPort.Text)];//這里的0,就是COM1,1是COM2。因為電腦創(chuàng)建了2個COM串口
serialPort.BaudRate = 9600;//波特率
serialPort.DataBits = 8;//數(shù)據(jù)位
serialPort.StopBits = System.IO.Ports.StopBits.One;//停止位
//serialPort.Encoding = System.Text.Encoding.GetEncoding("GB2312");//此行非常重要,解決接收中文亂碼的問題
serialPort.DataReceived += SerialPort_DataReceived;
// 打開串口
try
{
serialPort.Open();
}
catch (Exception ex)
{
//捕獲到異常信息,創(chuàng)建一個新的comm對象,之前的不能用了。
serialPort = new System.IO.Ports.SerialPort();
//將異常信息傳遞給用戶。
MessageBox.Show(ex.Message);
return;
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(500);
string txt = serialPort.ReadExisting();
this.Dispatcher.Invoke(new Action(() =>
{
txtReceive.Text = txt;
}));
}
private void btnSend_Click(object sender, RoutedEventArgs e)
{
serialPort.Write(txtSend.Text);
}
}
}
4.開啟2個COM
?
5.效果
直接運行2個客戶端
一個寫1端口,一個寫2端口,進行通信
可見,2個客戶端能進行信息傳送
二、USB通信
1.安裝Management
2.操作USB有2種方式
一是LibUsbDotNet
二是使用P/Invoke
3.代碼
using LibUsbDotNet.Main;
using LibUsbDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LibUsbDotNet.Info;
namespace USB
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//const int HID_DEVICE_VID = 0x093A;
//const int HID_DEVICE_PID = 0x2533;
const int HID_DEVICE_VID = 0x0461;
const int HID_DEVICE_PID = 0x4E28;
public MainWindow()
{
InitializeComponent();
}
private void btnQuery_Click(object sender, RoutedEventArgs e)
{
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\CIMV2");
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_USBHub");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection collection = searcher.Get();
string str = string.Empty;
foreach (ManagementObject device in collection)
{
str += device["Name"].ToString() + device["DeviceID"] + "\r";
//Console.WriteLine("設(shè)備名稱: " + device["Name"]);
//Console.WriteLine("設(shè)備ID: " + device["DeviceID"]);
//Console.WriteLine();
}
txtReceive.Text = str;
}
}
public static void GetUSBInfo()
{
UsbRegDeviceList allDevices = UsbDevice.AllDevices;
Console.WriteLine("Found {0} devices", allDevices.Count);
foreach (UsbRegistry usb in allDevices)
{
Console.WriteLine("----------------");
Console.WriteLine($"Device info: {usb.Device.Info.ProductString}");
Console.WriteLine($"Pid: {usb.Pid}, VID: {usb.Vid}");
}
Console.WriteLine(allDevices.Count);
}
private void btnOK_Click(object sender, RoutedEventArgs e)
{
//1.使用LibUsbDotNet
// 獲取所有已連接的USB設(shè)備
GetUSBInfo();
//var usbDevices = UsbDevice.AllDevices;
遍歷每個USB設(shè)備
//foreach (UsbDevice usbDevice in usbDevices)
//{
// // 打印USB設(shè)備的信息
// Console.WriteLine("設(shè)備描述: " + usbDevice.Info.DeviceDescription);
// Console.WriteLine("廠商ID: " + usbDevice.Info.UsbVendorId);
// Console.WriteLine("產(chǎn)品ID: " + usbDevice.Info.UsbProductId);
// Console.WriteLine();
// // 檢查是否為目標(biāo)設(shè)備(根據(jù)VID和PID判斷)
// if (usbDevice.Info.UsbVendorId == 0x1234 && usbDevice.Info.UsbProductId == 0x5678)
// {
// try
// {
// // 打開USB設(shè)備
// usbDevice.Open();
// // 進行你的USB通信操作(讀取或?qū)懭霐?shù)據(jù)等)
// // ...
// // 關(guān)閉USB設(shè)備
// usbDevice.Close();
// }
// catch (Exception ex)
// {
// Console.WriteLine("發(fā)生異常: " + ex.Message);
// }
// }
//}
//2.使用P/Invoke
IntPtr deviceHandle = UsbCommunication.OpenHidDevice(HID_DEVICE_VID, HID_DEVICE_PID);
if (deviceHandle != IntPtr.Zero)
{
byte[] sendData = { /* 發(fā)送的數(shù)據(jù) */ };
byte[] receiveData = new byte[64];
int bytesWritten = UsbCommunication.WriteHid(deviceHandle, sendData, sendData.Length);
int bytesRead = UsbCommunication.ReadHid(deviceHandle, receiveData, receiveData.Length);
// 處理接收到的數(shù)據(jù)
UsbCommunication.CloseHidDevice(deviceHandle);
}
else
{
Console.WriteLine("無法打開HID設(shè)備");
}
Console.WriteLine("按任意鍵退出...");
Console.ReadKey();
}
class UsbCommunication
{
// 調(diào)用底層庫進行USB通信,此處省略具體實現(xiàn),需要根據(jù)實際情況編寫相應(yīng)的P/Invoke聲明和方法實現(xiàn)
[DllImport("usb_communication.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr OpenHidDevice(int vid, int pid);
[DllImport("usb_communication.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int WriteHid(IntPtr handle, byte[] data, int length);
[DllImport("usb_communication.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int ReadHid(IntPtr handle, byte[] data, int length);
[DllImport("usb_communication.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CloseHidDevice(IntPtr handle);
}
}
}
4.效果
目前只是查詢出來4個USB設(shè)備,但是對USB進行發(fā)送和接收信息,還有報錯。這個似乎需要和硬件通信協(xié)議和數(shù)據(jù)傳輸規(guī)范有關(guān)系,否則好像成功不了,也不清楚可不可以使用虛擬的USB,類似于COM虛擬口一樣操作,暫時這么記錄吧。?
源碼
https://download.csdn.net/download/u012563853/88053882文章來源:http://www.zghlxwxcb.cn/news/detail-572575.html
來源:.net6中WPF的串口通信和USB通信_.net usb通信_故里2130的博客-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-572575.html
到了這里,關(guān)于.net6中WPF的串口通信和USB通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!