天天看点

C# USB异步通信——接收数据

C#

获取设备端点,点击Start,启动线程不断接收USB设备传来的数据,并保存到文件中。

窗体设计

C# USB异步通信——接收数据

源码

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Threading;

using System.IO;

using CyUSB;//需要添加CyUSB.dll引用

namespace USBSynDemo

{

    public partial class Form1 : Form

    {

        //USB设备相关字段

        USBDeviceList usbDevices;

        CyUSBDevice MyDevice;

        CyUSBEndPoint EndPoint;

        const int XFERSIZE=512;

        int BufSz = 512;

        int QueueSz = 1;//4

        int IsoPktBlockSize;

        bool bRunning = false;

        Thread tReceiveData = null;

        string filePath = @"D:\testdata.dat";//存入字节数据

        public Form1()

        {

            InitializeComponent();

            usbDevices = new USBDeviceList(CyConst.DEVICES_CYUSB);

            SetDevice();

        }

        private void SetDevice()

        {

            USBDevice dev = usbDevices[0x04B4, 0x1003];

            if (dev != null)

            {

                MyDevice = (CyUSBDevice)dev;

                GetEndpointsOfNode(MyDevice.Tree);

                if (EndPointsComboBox.Items.Count > 0)

                {

                    EndPointsComboBox.SelectedIndex = 0;

                    StartBtn.Enabled = true;

                }

            }

            else

            {

                StartBtn.Enabled = false;

                EndPointsComboBox.Items.Clear();

                EndPointsComboBox.Text = "";

            }

        }

        private void GetEndpointsOfNode(TreeNode devTree)

        {

            foreach (TreeNode node in devTree.Nodes)

            {

                if (node.Nodes.Count > 0)

                    GetEndpointsOfNode(node);

                else

                {

                    CyUSBEndPoint ept = node.Tag as CyUSBEndPoint;

                    if (ept == null)

                    {

                        //return;

                    }

                    else if (!node.Text.Contains("Control"))

                    {

                        CyUSBInterface ifc = node.Parent.Tag as CyUSBInterface;

                        string s = string.Format("ALT-{0}, {1} Byte, {2}", ifc.bAlternateSetting, ept.MaxPktSize, node.Text);

                        EndPointsComboBox.Items.Add(s);

                    }

                }

            }

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            if (EndPointsComboBox.Items.Count > 0)

                EndPointsComboBox.SelectedIndex = 0;

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)

        {

            if (usbDevices != null)

                usbDevices.Dispose();

        }

        //从列表中选择端点

        private void EndPointsComboBox_SelectedIndexChanged(object sender, EventArgs e)

        {

            // Get the Alt setting

            string sAlt = EndPointsComboBox.Text.Substring(4, 1);

            byte a = Convert.ToByte(sAlt);

            MyDevice.AltIntfc = a;

            // Get the endpoint

            int aX = EndPointsComboBox.Text.LastIndexOf("0x");

            string sAddr = EndPointsComboBox.Text.Substring(aX, 4);

            byte addr = (byte)Util.HexToInt(sAddr);

            EndPoint = MyDevice.EndPointOf(addr);

        }

        private void StartBtn_Click(object sender, EventArgs e)

        {

            if (MyDevice == null)

                return;

            if (StartBtn.Text.Equals("Start"))

            {

                EndPointsComboBox.Enabled = false;

                StartBtn.Text = "Stop";

                StartBtn.BackColor = Color.Pink;

                EndPoint.XferSize = XFERSIZE;

                if (EndPoint is CyIsocEndPoint)

                    IsoPktBlockSize = (EndPoint as CyIsocEndPoint).GetPktBlockSize(XFERSIZE);

                else

                    IsoPktBlockSize = 0;

                bRunning = true;

                tReceiveData = new Thread(new ThreadStart(XferThread));

                tReceiveData.IsBackground = true;

                tReceiveData.Priority = ThreadPriority.Highest;

                tReceiveData.Start();

            }

            else

            {

                if (tReceiveData.IsAlive)

                {

                    EndPointsComboBox.Enabled = true;

                    StartBtn.Text = "Start";

                    bRunning = false;

                    tReceiveData.Abort();

                    StartBtn.BackColor = Color.Aquamarine;

                }

            }

        }

        public unsafe void XferThread()

        {

            // Setup the queue buffers

            byte[][] cmdBufs = new byte[QueueSz][];

            byte[][] xferBufs = new byte[QueueSz][];

            byte[][] ovLaps = new byte[QueueSz][];

            ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][];

            int xStart = 0;

            try

            {

                LockNLoad(ref xStart, cmdBufs, xferBufs, ovLaps, pktsInfo);

            }

            catch (NullReferenceException e)

            {

                // This exception gets thrown if the device is unplugged 

                // while we're streaming data

                e.GetBaseException();

            }

        }

        public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)

        {

            cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED)? BufSz : 0)];

            xBufs[j] = new byte[BufSz];

            oLaps[j] = new byte[CyConst.OverlapSignalAllocSize];

            pktsInfo[j] = new ISO_PKT_INFO[1];

            fixed (byte* tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j])  // Pin the buffers in memory

            {

                OVERLAPPED* ovLapStatus = (OVERLAPPED*)tL0;

                ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0);

                // Pre-load the queue with a request

                int len = BufSz;

                EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]);

                j++;

                if (j < QueueSz)

                    LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo);  // Recursive call to pin next buffers in memory

                else

                    XferData(cBufs, xBufs, oLaps, pktsInfo);          // All loaded. Let's go!

            }

        }

        public unsafe void XferData(byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)

        {

            int k = 0;

            int len = 0;

            for (; bRunning; )

            {

                // WaitForXfer

                fixed (byte* tmpOvlap = oLaps[k])

                {

                    OVERLAPPED* ovLapStatus = (OVERLAPPED*)tmpOvlap;

                    if (!EndPoint.WaitForXfer(ovLapStatus->hEvent, 500))

                    {

                        EndPoint.Abort();

                        PInvoke.WaitForSingleObject(ovLapStatus->hEvent, 500);

                    }

                }

                len = BufSz;

                // FinishDataXfer

                if (EndPoint.FinishDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k]))

                {

                    //保存接收的数据到文件中

                    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);

                    fs.Write(xBufs[k], 0, len);

                    fs.Close();

                }

                // Re-submit this buffer into the queue

                EndPoint.BeginDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k]);

                k++;

                if (k == QueueSz)  // Only update displayed stats once each time through the queue

                {

                    k = 0;

                }

            } // End infinite loop

        }

    }

}