前言
在网上找了一圈发现,用C#来开发上位机还是比较简单的,因此在这里和大家分享一下开发的过程。
一、准备数据
将STM32的主函数main.c中修改一下发送的数据。
while (1)
{
HAL_Delay(1000);
debug("usb send data\r\n");
USB_Recive_Buffer[10]=sendCount++;
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, USB_Recive_Buffer, 64);
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_Delay(500);
//USB_Recive_Buffer[63]='\0';
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)USB_Recive_Buffer, 64);
HAL_Delay(1000);
debug("USB_Received_Count=== %d\r\n",USB_Received_Count);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
二、在VS中开发上位机
1.引入国外大神写的USB通讯库HidLibary
2.新建HID管理类 CustomHIDManager.cs
关键代码如下(示例):
class MyHIDManager : IDisposable
{
//自定义usb设备的PID和VID
private const int ProductId = 0x5753;
private const int VendorId = 0x0482;
//usb设备
private HidDevice device;
//标志位
private bool attached = false;
private bool connectedToDriver=false;
private bool disposed = false;
//当设备插入时,触发的事件(可以暂时理解为函数指针,其实c#中委托是函数指针,事件可以理解为函数指针数组)
public event EventHandler DeviceInserted;
//当设备移除时,触发的事件(可以暂时理解为函数指针)
public event EventHandler DeviceRemoved;
//自定义数据接收的事件触发(可以暂时理解为函数指针)
public event EventHandler<CustomHIDEventArgs> DataReceived;
public MyHIDManager()
{
}
/// <summary>
/// 打开设备
/// </summary>
public bool OpenDevice()
{
device = HidDevices.Enumerate(VendorId, ProductId).FirstOrDefault();
if (device !=null)
{
connectedToDriver = true;
device.OpenDevice();
device.Inserted += DeviceInsertedHandler;
device.Removed += DeviceRemovedHandler;
device.MonitorDeviceEvents = true;
device.ReadReport(OnReport);
return true;
}
return false;
}
/// <summary>
/// 关闭设备
/// </summary>
public void CloseDevice()
{
device.CloseDevice();
connectedToDriver = false;
}
//可以理解为插入后执行的回调函数
private void DeviceInsertedHandler()
{
attached = true;
if (DeviceInserted!=null)
{
DeviceInserted(this, EventArgs.Empty);
}
device.ReadReport(OnReport);
}
//可以理解为拔掉后执行的回调函数
private void DeviceRemovedHandler()
{
attached = false;
if (DeviceRemoved != null)
{
DeviceRemoved(this, EventArgs.Empty);
}
}
//可以理解为数据接收后执行的函数
private void OnReport(HidReport report)
{
if (attached == false) return;
if (report.Data.Length>6)
{
//1-解析report.Data
//2-解析成功的话
if (true)
GenerateEvents(report.Data[10]);
}
//为什么递归呀??
//Console.WriteLine("调用了device.ReadReport(OnReport)");
device.ReadReport(OnReport);
}
private void GenerateEvents(int arg)
{
OnDataReceived(arg);
}
private void OnDataReceived(int arg)
{
if (DataReceived != null)
DataReceived(this, new CustomHIDEventArgs(arg));
}
...
}
自定义的传上来的数据的解析,或者协议等等
public class CustomHIDEventArgs : EventArgs
{
public CustomHIDEventArgs(int arg)
{
Arg = arg;
}
private int _arg;
public int Arg { get => _arg; set => _arg = value; }
}
}
主函数就很简单了
class Program
{
static MyHIDManager myHIDManager = new MyHIDManager();
static void Main(string[] args)
{
if (myHIDManager.OpenDevice())
{
myHIDManager.DeviceInserted += new EventHandler(usbInsertedFunc);
myHIDManager.DeviceRemoved += new EventHandler(usbRemovedFunc);
myHIDManager.DataReceived += new EventHandler<CustomHIDEventArgs>(usbDataReceiveFunc);
Console.WriteLine("已经识别到USB ,按任意键退出");
Console.ReadKey();
myHIDManager.CloseDevice();
}
else
{
Console.WriteLine("未识别到USB ,按任意键退出");
Console.ReadKey();
}
}
private static void usbDataReceiveFunc(object sender, CustomHIDEventArgs e)
{
Console.Write("已经收到USB HID设备发送的数据----");
Console.WriteLine(e.Arg);
}
private static void usbRemovedFunc(object sender, EventArgs e)
{
Console.WriteLine("我的USB HID 设备已经拔出");
}
private static void usbInsertedFunc(object sender, EventArgs e)
{
Console.WriteLine("我的USB HID 设备已经插入");
}
}
3.运行结果
总结
水平有限,有不对的地方请大家批评指正。谢谢