之前写过串口通信,不过是winform的。
c#使用串口进行通信_c# 串口通信_故里2130的博客-CSDN博客
今天说一下,.net6中wpf的串口通信和USB通信,在工控行业中,这2种的方式非常多,还有网口通信,它们都是用来和硬件打交道的,进行交互信息。
一、串口通信
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="发送" Click="btnSend_Click"/><TextBlock Text="接收的数据"/><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。因为电脑创建了2个COM串口serialPort.BaudRate = 9600;//波特率serialPort.DataBits = 8;//数据位serialPort.StopBits = System.IO.Ports.StopBits.One;//停止位//serialPort.Encoding = System.Text.Encoding.GetEncoding("GB2312");//此行非常重要,解决接收中文乱码的问题serialPort.DataReceived += SerialPort_DataReceived;// 打开串口try{serialPort.Open();}catch (Exception ex){//捕获到异常信息,创建一个新的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("设备名称: " + device["Name"]);//Console.WriteLine("设备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设备GetUSBInfo();//var usbDevices = UsbDevice.AllDevices;遍历每个USB设备//foreach (UsbDevice usbDevice in usbDevices)//{// // 打印USB设备的信息// Console.WriteLine("设备描述: " + usbDevice.Info.DeviceDescription);// Console.WriteLine("厂商ID: " + usbDevice.Info.UsbVendorId);// Console.WriteLine("产品ID: " + usbDevice.Info.UsbProductId);// Console.WriteLine();// // 检查是否为目标设备(根据VID和PID判断)// if (usbDevice.Info.UsbVendorId == 0x1234 && usbDevice.Info.UsbProductId == 0x5678)// {// try// {// // 打开USB设备// usbDevice.Open();// // 进行你的USB通信操作(读取或写入数据等)// // ...// // 关闭USB设备// usbDevice.Close();// }// catch (Exception ex)// {// Console.WriteLine("发生异常: " + ex.Message);// }// }//}//2.使用P/InvokeIntPtr deviceHandle = UsbCommunication.OpenHidDevice(HID_DEVICE_VID, HID_DEVICE_PID);if (deviceHandle != IntPtr.Zero){byte[] sendData = { /* 发送的数据 */ };byte[] receiveData = new byte[64];int bytesWritten = UsbCommunication.WriteHid(deviceHandle, sendData, sendData.Length);int bytesRead = UsbCommunication.ReadHid(deviceHandle, receiveData, receiveData.Length);// 处理接收到的数据UsbCommunication.CloseHidDevice(deviceHandle);}else{Console.WriteLine("无法打开HID设备");}Console.WriteLine("按任意键退出...");Console.ReadKey();}class UsbCommunication{// 调用底层库进行USB通信,此处省略具体实现,需要根据实际情况编写相应的P/Invoke声明和方法实现[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设备,但是对USB进行发送和接收信息,还有报错。这个似乎需要和硬件通信协议和数据传输规范有关系,否则好像成功不了,也不清楚可不可以使用虚拟的USB,类似于COM虚拟口一样操作,暂时这么记录吧。
源码
https://download.csdn.net/download/u012563853/88053882