




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、串口通信中接收數(shù)據(jù)時延遲處理與緩存處理的解決方案(C#)利用串口進行通信,當(dāng)發(fā)送方(A)將數(shù)據(jù)寫入串口后,通過無線或有線方式將數(shù)據(jù)傳送給接收方(B),B 通過調(diào)用串口讀方法 comm.read(參數(shù))即可將數(shù)據(jù)讀出。原理十分簡單,但最近在利用串口處理 SM-42 無線傳輸時,數(shù)據(jù)總是一段一段的傳到 B,并不能在 comm_DataReceived 方法中單純使用 read 方法將數(shù)據(jù)接收完全。我知道用緩存機制,但由于經(jīng)驗少(正在實習(xí)),到網(wǎng)上找了找大牛們的方法,并結(jié)合自己的理解,發(fā)現(xiàn)有兩種方法可以處理。方法一:comm_DataReceived(Comm 控件的數(shù)據(jù)接收方法,當(dāng)有數(shù)據(jù)來臨時會觸
2、發(fā))會創(chuàng)建一個線程(,因為之前不知道它另辟線程,所以自己編寫了一個線程處理函數(shù)),因此當(dāng)串口在等待數(shù)據(jù)時,不影響主窗體或主線程的操作。所以當(dāng)數(shù)據(jù)到來時,可以通過 Thread.Sleep(100)讓接收函數(shù)休息 100 毫秒,這 100 毫秒做什么用呢?就是讓所有的數(shù)據(jù)都到達 B 時再,這樣就逃避了分批到達。很明顯,這是在糊弄。因為萬一 100毫秒都不夠呢?所以,方法二更合適。代碼1 private void comm_DataReceived(objecder, EventArgs e) 2 Thread.Sleep(100); /等待 100 毫秒nReviceBytesNum =comm
3、.BytesToRead; /收到的字節(jié)數(shù)。byte ReadBuf = new bytenReviceBytesNum; /定義接收字節(jié)數(shù)組comm.Read(ReadBuf, 0, nReviceBytesNum); /接收數(shù)據(jù) 7 方法二:使用緩存機制完成。首先通過定義一個成員變量 List buffer = new List(4096);用來存放所有的數(shù)據(jù),在接收函數(shù)里,通過 buffer.AddRange()方法不斷地將接收到的數(shù)據(jù)加入到 buffer 中,并同時對 buffer 中的數(shù)據(jù)進行檢驗,如果達到一定的長度并且校驗結(jié)果正確(校驗方法在發(fā)送方和接收方一致),再進行處理。具體代
4、碼如下:代碼privaist buffer = new List(4096);private void sp_DataReceived(objecder, EventArgs e) /sp 是串口控件n = sp.BytesToRead; byte buf = new byten; sp.Read(buf, 0, n);/1.緩存數(shù)據(jù) buffer.AddRange(buf);/2.完整性判斷while (buffer.Count = 4)/至少包含幀頭(2 字節(jié))、長度(1 字節(jié))、校驗位(1 字節(jié));根據(jù)設(shè)計不同而不同/2.1 查找數(shù)據(jù)頭if (buffer0 = 0 x01) /傳輸數(shù)據(jù)
5、有幀頭,用于判斷l(xiāng)en = buffer2;if (buffer.Count len + 4) /數(shù)據(jù)區(qū)尚未接收完整break;跨線程及修改控件屬性的解決方案在上一篇文章中,寫了一些串口通信時數(shù)據(jù)接收的內(nèi)容,其中有一行代碼有個提問:在數(shù)據(jù)接收線程中,當(dāng)接收到數(shù)據(jù)并且校驗正確后,我怎么顯示這些數(shù)據(jù)到窗體中呢?要顯示數(shù)據(jù),必須要 主線程(A)的各種控件,而數(shù)據(jù)接收是另一個線程(B)。有兩種方案可以解決這個問題,和上文一樣,也是第二個較好。方法一:取消跨線程操作檢查當(dāng)線程 B 在線程 A 創(chuàng)建的控件時,線程 A 會對控件的線程鎖進行檢驗,當(dāng)多個線程同時對控件進行寫操作時,必然產(chǎn)生,因此此時的程序會非
6、常不穩(wěn)定,經(jīng)常突然就退出,Debug 顯示原因是跨線程操作控件了。既然如此,那就讓線程 A 不去檢驗其他線程了,在 Form_Load 函數(shù)里加一句:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;就萬事大吉了。很顯然,這種方法不使用。方法二:使用機制原理:有一個D,他負責(zé)溝通主線程 A 和其他線程 B,當(dāng)是主線程操作控件時,正常執(zhí)行;當(dāng)是其他線程 B操作控件時,通知D,之后D 喚醒主線程 A,告訴主線程 A 去更改控件的一些屬性,顯然,這樣一來,就不存在跨線程操作了,所有的任務(wù)由D 來完成。示例代碼如下
7、:使用 delegate 定義一個delShow。在其他線程中控件 textbox1 時,直接調(diào)用 showData(其他線程);就可以了,showData 函數(shù)能自動區(qū)分是否是主線程。delegate void delShow(); /將對控件的操作寫到一個函數(shù)中/得到完整的數(shù)據(jù),到ReceiveBytes 中進行校驗 buffer.CopyTo(0, ReceiveBytes, 0, len + 4); byte jiaoyan; /開始校驗jiaoyan = this.JY(ReceiveBytes); if (jiaoyan != ReceiveByteslen+3)/校驗失敗,最后一
8、個字節(jié)是校驗位buffer.RemoveRange(0, len + 4); MessageBox.Show(數(shù)據(jù)包不正確!); continue;buffer.RemoveRange(0, len + 4);/執(zhí)行其他代碼,對數(shù)據(jù)進行處理。else /幀頭不正確時,記得清除buffer.RemoveAt(0);在方法二中,有一句“執(zhí)行其他代碼,對數(shù)據(jù)進行處理”,如果這些代碼涉及到主線程的控件比如 Label,TextBox,就要涉及跨線程控件。(串口的 DataReceived 方創(chuàng)建新線程,這在本文開始時已經(jīng)說明)對于 跨線程及更改控件屬性,也有兩種方法,下一篇文章再介紹。12345678
9、910111213delegate void delShow(string key);private void showData(String para)if (!InvokeRequired)textBox1.Text = para;elsethis.Invoke(new delShow(showData), para);.NET 提供了 SerialPort 類進行串口通信,使用很簡單,連我這個.NET 新手也能很快上手.以下是從網(wǎng)上找到并自己修改后的參考代碼:using System;using System.Collections.Generic;using System.Linq;C
10、#中使用 SerialPort 類實現(xiàn)簡單串口編程給你改了改,這樣看起來好一點private void showData(String para) if (!textbox1.InvokeRequired) /不需要喚醒,就是創(chuàng)建控件的線程/如果是創(chuàng)建控件的線程,直接正常操作textbox1.Text = para;else /非創(chuàng)建線程,用進行操作delShow ds = new delShow(showData);/喚醒主線程,可以傳遞參數(shù),也可以為null,即不傳參數(shù) Invoke(ds, new objectpara);/其他線程使用,具體線程的建立自己去查看相關(guān)書籍 showData
11、(其他線程);#3 樓 2011-01-21 17:15 單程列車?45678910111213141516171819202122232425262728293031323334353637383940using using using using using using using using using usingusingSystem.Text; System.Windows; System.Windows.Controls;System.Windows.Data;System.Windows.System.Windows.Input; System.Windows.Media;s;S
12、ystem.Windows.Media.Imaging;System.Windows.Navigation;System.Windows.ShSystem.IO.Ports;s;namespacem/ Window1.xaml 的交互邏輯public partial class Window1 : Windowpublic Window1()InitializeComponent();/定義 SerialPort 對象SerialPort port1;/初始化SerialPort 對象方法.PortName 為COM 口名稱,例如COM1,COM2等,注意是string 類型public vo
13、id InitCOM(string PortName)port1 = new SerialPort(PortName);port1.BaudRate = 9600;/波特率 port1.Parity = Parity.None;/無奇偶校驗位its = Stits.Two;/兩個停止位port1.Stport1.Handshake = Handshake.RequestToSend;/控制協(xié)議port1.ReceivedBytesThreshold = 4;/設(shè)置 DataReceived 事件發(fā)生前輸入緩沖區(qū)中的字節(jié)數(shù)port1.DataReceived += new SerialDataR
14、eceivedEvenndlort1_DataReceived);/DataReceived 事件委托4142434445464748/DataReceived 事件委托方法private void port1_DataReceived(objectryder, SerialDataReceivedEventArgs e)StringBuilder currentline = new StringBuilder();495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
15、94/循環(huán)接收數(shù)據(jù)while (port1.BytesToRead 0)char ch = (char)port1.ReadByte(); currentline.Append(ch);/在這里對接收到的數(shù)據(jù)進行處理/currentline= new StringBuilder();catch(ExceptionConsole.Wriex)ine(ex.Message.ToString();/打開串口的方法public void OpenPort()tryport1.Open();catch if (port1.IsOpen)Console.WrielseConsole.Wriine(the
16、port is opened!);ine(failure to open the port!);/關(guān)閉串口的方法public void ClosePort()port1.Close();if (!port1.IsOpen)Console.Wriine(the port is already closed!);/向串口發(fā)送數(shù)據(jù)C#的 usb 通訊編程using System;using System.Collections.Generic;usingponentM;using System.Data; using System.Drawing;using System.Text;95public
17、 voidmand(stringdString) 96byte WriteBuffer = Encoding.ASCII.GetBytes(dString);port1.Write(WriteBuffer, 0, WriteBuffer.Length); 99100/調(diào)用實例private void btnOpen_Click(objecder, RoutedEventArgs e)103/我現(xiàn)在用的COM1 端口,按需要可改成COM2,COM3InitCOM(COM1);OpenPort();107108109 值得注意的是:port1.ReceivedBytesThreshold = 4;
18、 ReceivedBytesThreshold 屬性設(shè)置觸發(fā)一次 DataReceived 事件時將接收到的數(shù)據(jù)字節(jié)數(shù).由于硬件是一次發(fā)上來 4 個字節(jié)估設(shè)置為 4.如果不能正確設(shè)置這個屬性的話,在 SerialPort 對象第一次觸發(fā) DataReceived 事件時還是正確的(4 個字節(jié)),但是從第二次觸發(fā)之后都是一個字節(jié)觸發(fā)一次 DataReceived 事件.為什么這樣搞不清楚.如果在 DataReceived 委托事件中使用了不是 DataReceived 委托事件所程創(chuàng)建的 UI 控件,函數(shù)等,需要使用到 Dispatcher 類來達到線程安全,不然會報錯.以下是 MSDN 中 D
19、ispatcher 類的例子(XAML),簡單明了:1 private delegate void AddTextDelegate(Panel p, String text); 23 private void AddText(Panel p, String text) 4 p.Children.Clear();p.Children.Add(new TextBlock Text = text ); 7 89 private void TestBeginInvokeWithParameters(Panel p) 10 if (p.Dispatcher.CheckAcs() AddText(p, A
20、dded directly.);else p.Dispatcher.BeginInvoke(new AddTextDelegate(AddText), p, Added by Dispatcher.); 14 using System.Windows.Forms;using System.IO;namespace U 盤更新public partial class Form1 : Formpublic const public const public const public const public const public const public const public const
21、public const public const public const public constpublic constWM_DEVICECHANGE = 0 x219; DBT_DEVICEARRIVAL = 0 x8000; DBT_CONFIGCHANGECANCELED = 0 x0019; DBT_CONFIGCHANGED = 0 x0018; DBT_CUSTOMEVENT = 0 x8006; DBT_DEVICEQUERYREMOVE = 0 x8001; DBT_DEVICEQUERYREMOVEFAILED = 0 x8002; DBT_DEVICEREMOVECO
22、MPLETE = 0 x8004; DBT_DEVICEREMOVEPENDING = 0 x8003; DBT_DEVICETYPESPECIFIC = 0 x8005; DBT_DEVNODES_CHANGED = 0 x0007;DBT_QUERYCHANGECONFIG = 0 x0017;DBT_USERDEFINED = 0 xF;public Form1()InitializeComponent();private void Form1_Load(objecder, EventArgs e)protected override void WndProc(ref Message m
23、)tryif (m.Msg = WM_DEVICECHANGE)switch (m.ram.To32()case WM_DEVICECHANGE:break;case DBT_DEVICEARRIVAL:/U 盤 DriveInfo s = DriveInfo.GetDrives(); foreach (DriveInfo drive in s)if (drive.DriveType = DriveType.Removable)listBox1.Items.Add(U 盤已break;,盤符為: + drive.Name.ToString();break;case DBT_CONFIGCHAN
24、GECANCELED:break;case DBT_CONFIGCHANGED:break;case DBT_CUSTOMEVENT:break;case DBT_DEVICEQUERYREMOVE:break;case DBT_DEVICEQUERYREMOVEFAILED:break;case DBT_DEVICEREMOVECOMPLETE: /U 盤卸載break;case DBT_DEVICEREMOVEPENDING:break;case DBT_DEVICETYPESPECIFIC:break;case DBT_DEVNODES_CHANGED:break;case DBT_QU
25、ERYCHANGECONFIG:break;case DBT_USERDEFINED:break; default:break;catch (Exception ex)MessageBox.Show(ex.Message);base.WndProc(ref m);) ;9( 轉(zhuǎn)串口突然拔出檢測解決方案最近做虛擬串口通訊程序(IRDA-USB-串口),由于是 USB 設(shè)備所以在通訊過程中有可能把串口拔出,程序需要實時檢測到串口拔出。并把正在執(zhí)行的任務(wù)結(jié)束關(guān)閉串口,給出提示。由于程序是 C#做的,C#在操作底層比較不方便,需要調(diào)用較多的 API 函數(shù)。開始的方法是先捕獲 USB 設(shè)備的拔出,再查找
26、HKEY_LOCAL_MACHINE/HAEDWARE/D中的串口是否已經(jīng)不存在。后來發(fā)現(xiàn)這種辦法不可行.后來查找表的HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/DeviceClasses/a5dcbf10-6530-11d2-901f-00c04 fb951ed 中的相應(yīng)項看是否 LInked 等于零,如果是就是你的 usb 設(shè)備拔出了。而且你還要檢測是不是你的那個串口,這樣算是可以解決問題.。之后我有想用異常的方法來解決這個問題,首先還是捕獲 USB 設(shè)備的拔出消息,由于.NET 并不知道串口的拔出,要是該串口正在使用,這是對串口
27、的是最好有方便的。代碼如下:將會產(chǎn)生異常,所以通過捕獲異常來處理protected override void WndProc(ref Message m)if (m.Msg = 0 x0219)/設(shè)備被拔出if (m.ram.To32() = 0 x8004)/usb 串口if (對串口進行操作)/產(chǎn)生異常關(guān)閉串口base.WndProc(ref m);當(dāng)設(shè)備入/拔出的時候,WINDOWS 會向每個窗體發(fā)送 WM_DEVICECHANGE消息,當(dāng)消息的ram 值ram 值等于等于 DBT_DEVICEARRIVAL 時,表示 Media 設(shè)備入并且已經(jīng)可用;如果DPLETE,表示 Media
28、 設(shè)備已經(jīng)被移出。它們的 lParam 都指向一個 DEV_BROADCAST_HDR 結(jié)構(gòu)體,其如下:1 typedef struct _DEV_BROADCAST_HDR2 3DWORD dbch_size;45DWORD dbch_devicetype;DWORD dbch_;6 DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;這個結(jié)構(gòu)體僅僅是一個“頭”(HDR),其后還有附加數(shù)據(jù),dbch_size 表示結(jié)構(gòu)體實例的字節(jié)數(shù),當(dāng)其中的dbch_devicetype 字等于 DBT_DEVTYP_VOLUME 時,表示當(dāng)前設(shè)備是邏輯驅(qū)動器,且 lParam 實
29、際上指向的應(yīng)該是 DEV_BROADCAST_VOLUME 結(jié)構(gòu)體實例(真佩服這種邏輯),DEV_BROADCAST_VOLUME 結(jié)構(gòu)體如下:1 typedef struct _DEV_BROADCAST_VOLUME 23456DWORD dbcv_size;DWORD dbcv_devicetype;DWORD dbcv_;DWORD dbcv_unitmask;WORD dbcv_flags;7 DEV_BROADCAST_VOLUME, *PDEV_BROADCAST_VOLUME;其中 dbcv_unitmask 字段表示當(dāng)前改變的驅(qū)動器掩碼,第一位表示驅(qū)動器號 A,第二位表示驅(qū)動
30、器號 B,第三位表示驅(qū)動器號 C,以此類推 dbcv_flags 表示驅(qū)動器的類別,如果等于 1,則是光盤驅(qū)動器;如果是 2,則是網(wǎng)絡(luò)驅(qū)動器;如果是硬盤、U 盤則都等于 0所以,我只需要在程序中捕捉 WM_DEVICECHANGE代碼:消息,然后根據(jù)具體情況去處理即可,下面是測試using System;using System.Runtime.eropServi using System.Collections.Generic;usingponentM;using System.Data; using System.Drawing; using System.Text;using Syste
31、m.Windows.Forms;namespace UDiskDetectpublic partial class Form1 : Formpublic Form1()ponent();private void Form1_Load(objecder, EventArgs e)StructLayout(LayoutKind.Sequential) struct DEV_BROADCAST_HDRpublic U public Upublic U32 dbch_size;32 dbch_devicetype;32 dbch_;StructLayout(LayoutKind.Sequential)
32、 struct DEV_BROADCAST_VOLUMEpublic U public U public U public Upublic U32 dbcv_size;32 dbcv_devicetype;32 dbcv_;32 dbcv_unitmask;16 dbcv_flags;protected override void DefWndProc(ref Message m)if (m.Msg = 0 x0219)/WM_DEVICECHANGEswitch (m.ram.To32()case 0 x8000:/DBT_DEVICEARRIVALDEV_BROADCAST_HDR dbh
33、dr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LPara m, typeof(DEV_BROADCAST_HDR);if (dbhdr.dbch_devicetype = 0 x00000002)/DBT_DEVTYP_VOLUMEDEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME);if (dbv.dbcv_flags = 0) AddVolumes(GetVolumes(d
34、bv.dbcv_unitmask);break;case 0 x8004:/DPLETEDEV_BROADCAST_HDR dbhdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR);if (dbhdr.dbch_devicetype = 0 x00000002)/DBT_DEVTYP_VOLUMEDEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_B
35、ROADCAST_VOLUME);if (dbv.dbcv_flags = 0) RemoveVolumes(GetVolumes(dbv.dbcv_unitmask);break;base.DefWndProc(ref m);/ / 根據(jù)驅(qū)動器掩碼返回驅(qū)動器號數(shù)組/ / 掩碼/ 返回驅(qū)動器號數(shù)組 public sic char GetVolumes(U32 Mask)List Volumes = new List();C#實現(xiàn) USB 接口的程序代碼C#實現(xiàn) USB 接口的程序代碼.namespace ConsoleApplication1class Programsic void Main
36、(string args)USB usb;for (i = 0; i 32; i+)up = (u)Math.(2, i); if (p | Mask) = p)Volumes.Add(char)(A + i);return Volumes.ToArray();public void AddVolumes(char Volumes)foreach (char volume in Volumes) listBox1.Items.Add(volume);public void RemoveVolumes(char Volumes)foreach (char volume in Volumes) l
37、istBox1.Items.Remove(volume);usb = new UDisk();/U 盤usb.OutputFile();/從U 盤讀出文件usb.InputFile();/往U 盤寫入文件usb.Dise();/拔出U 盤Console.Wriine();usb = new MDisk();/移動硬盤usb.OutputFile();/從移動硬盤讀出文件usb.InputFile();/往移動硬盤寫入文件usb.Dise();/拔出移動硬盤Console.Wriine();usb = new MP4();/MP4usb.OutputFile();/從MP4 讀出文件usb.In
38、putFile();/往 MP4 寫入文件usb.Dise();/拔出MP4Console.ReadKey();/USB 接口publicerface USB : IDisvoid OutputFile();/讀出文件 void InputFile();/寫入文件able/U 盤public class UDisk : USBpublic UDisk()Console.Wriine(U 盤準備就緒.);public void OutputFile()Console.Wriine(從U 盤讀出文件);public void InputFile()Console.Wriine(往U 盤寫入文件);
39、public void DisConsole.Wrie()ine(U 盤已被拔出);/移動硬盤public class MDisk : USBpublic MDisk()Console.Wriine(移動硬盤準備就緒.);public void OutputFile()Console.Wriine(從移動硬盤讀出文件);public void InputFile()Console.Wriine(往移動硬盤寫入文件);public void DisConsole.Wrie()ine(移動硬盤已被拔出);/MP4public class MP4 :public MP4()Console.WriUS
40、Bine(MP4 準備就緒.);public void OutputFile()Console.Wriine(從MP4 讀出文件);public void InputFile()Console.Wriine(往MP4 寫入文件);public void Dise()C#:USB 設(shè)備枚舉(一)DeviceIoControl 的 PInvoke開發(fā)環(huán)境:Visual Studio V2010.NET Framework 4 Cnt Profile版本歷史:V1.02011 年 10 月 10 日實現(xiàn)對 DeviceIoControl 接口的 PInvoke參考資料:*/using System;
41、using System.Runtime.eropServi;namespaplash.IO.PORTS#region ENUMpublic enum USB_HUB_NODE : uUsbHub,UsbMIParentpublic enum USB_CONNECTION_SUSNoDeviceConnected,DeviceConnected,Console.Wriine(MP4 已被拔出);DeviceFailedEnumeration,DeviceGeneralFailure,DeviceCausedOvercurrent,DeviceNotEnougher,DeviceNotEnoug
42、hBandwidth,DeviceHubNestedTooDeeply,DeviceInLegacyHubpublic enum USB_DEVICE_SPEED : byteUsbLowSpeed,/ 低速 USB 1.1UsbFullSpeed,/全速 USB1.1UsbHighSpeed,/高速 USB2.0UsbSuperSpeed/極速 USB3.0#endregionpublicpartial claSBernalconst32IOCTL_GET_HCD_DRIVERKEY_NAME = 0 x220424;ernalconst32IOCTL_USB_GET_ROOT_HUB_NA
43、ME = 0 x220408;ernalconst32IOCTL_USB_GET_NODE_CONNECTION_NAME = 0 x220414;ernalconst32IOCTL_USB_GET_NODE_INFORMATION = 0 x220408;ernalconst32 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0 x220448;ernal const32 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0 x220410;ernal const32UM_USB_STRING_LE
44、NGTH = 255;ernal const32 USB_STRING_DESCRIPTOR_TYPE = 3;StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)ernal struct USB_HCD_DRIVERKEY_NAMEpublic32 ActualLength;MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)public String Name;#region USB_NODE_INFORMATIONStructLayout(LayoutKind.Sequen
45、tial, Pack= 1)ernal struct USB_HUB_DESCRIPTORpublicBytebDescriptorLength;publicBytebDescriptorType;/ 描述符類型:0 x29publicBytebNumberOfPorts;/ 支持的下游端口數(shù)目public16 wHubCharacteristics;/ 特征描述publicByte berOnToerGood;/ 從端口加電到端口正常工作的時間間隔(以 2ms 為)public Byte bHubControlCurrent;/ 設(shè)備所需最大電流MarshalAs(UnmanagedType
46、.ByValArray,SizeConst = 64)public Byte bRemoveAnderMask;/ 指示連接在集線器端口的設(shè)備是否可移走StructLayout(LayoutKind.Sequential)ernal struct USB_HUB_INFORMATIONpublic USB_HUB_DESCRIPTOR HubDescriptor;public Byte HubIsBusered;StructLayout(LayoutKind.Sequential)ernal struct USB_MI_PARENT_INFORMATIONpublic32 NumberOfer
47、fa;StructLayout(LayoutKind.Explicit)ernal struct UsbNodeUnionFieldOffset(0)public USB_HUB_INFORMATION HubInformation;FieldOffset(0)public USB_MI_PARENT_INFORMATION MiParentInformation;StructLayout(LayoutKind.Sequential)ernal struct USB_NODE_INFORMATIONpublic USB_HUB_NODE NodeType;public UsbNodeUnion
48、 u;#endregion#region USB_NODE_CONNECTION_INFORMATIONStructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_DEVICE_DESCRIPTORpublicByte bLength;publicByte bDescriptorType;publicU16 bcdUSB;publicBytebDeviceClass;publicBytebDeviubClass;publicBytebDeviceProtocol;publicBytebMaxPacketSize0;publicU16i
49、dVendor;publicU16idProduct;publicU16bcdDevice;publicByteiManufacturer;publicByteiProduct;publicByteiSerialNumber;publicBytebNumConfigurations;StructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_ENDPO_DESCRIPTORpublicBytebLength;publicBytebDescriptorType;publicBytebEndpoAddress;publicBytebmAt
50、tributes;publicU16 wMaxPacketSize;publicByte berval;StructLayout(LayoutKind.Sequential, Pack=1)ernal struct USB_PIPE_INFOpublic USB_ENDPO_DESCRIPTOR EndpoDescriptor;public U32 ScheduleOffset;StructLayout(LayoutKind.Sequential, Pack = 1)ernal struct USB_NODE_CONNECTION_INFORMATION_EXpublic32 Connecti
51、onIndex;publicUSB_DEVICE_DESCRIPTOR DeviceDescriptor;publicByteCurrentConfigurationValue;publicByteSpeed;publicByteDeviceIsHub;public16 DeviceAddress;public32 NumberOfOpenPipes;publicUSB_CONNECTION_SUS ConnectionSus;MarshalAs(UnmanagedType.ByValArray, SizeConst= 32)public USB_PIPE_INFO PipeList;#end
52、region#region USB_DESCRIPTOR_REQUESTStructLayout(LayoutKind.Sequential)ernal struct USB_SETUP_PACKETpublicByte bmRequest;publicByte bRequest;publicU16wValue;publicU16wIndex;publicU16wLength;StructLayout(LayoutKind.Sequential, CharSet= CharSet.Auto)ernal struct USB_STRING_DESCRIPTORpublic Byte bLengt
53、h;public Byte bDescriptorType;MarshalAs(UnmanagedType.ByValTStr,SizeConst=UM_USB_STRING_LENGTH)public String bString;StructLayout(LayoutKind.Sequential)ernal struct USB_DESCRIPTOR_REQUESTpublic32 ConnectionIndex;publicUSB_SETUP_PACKET SetupPacket;publicUSB_STRING_DESCRIPTOR Data;#endregion#region US
54、B_NODE_CONNECTION_DRIVERKEY_NAMEStructLayout(LayoutKind.Sequential, CharSet= CharSet.Auto)ernal structUSB_NODE_CONNECTION_DRIVERKEY_NAMEpublic32 ConnectionIndex;public32 ActualLength;MarshalAs(UnmanagedType.ByValTStr, SizeConst =UM_USB_STRING_LENGTH)public String DriverKeyName;#endregion#region Devi
55、ceIoControlDllImport(kernel32.dll, CharSet = CharSet.Ansi,SetLastError=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,Ptr lpInBuffer,32 nInBufferSize,ref USB_HCD_DRIVERKEY_NAME lpOutBuffer,32 nOutBufferSize,out32 nBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = C
56、harSet.Ansi,SetLastError=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_INFORMATION lpInBuffer,32 nInBufferSize,ref USB_NODE_INFORMATION lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = CharSet.Ansi, SetLastError=
57、true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_CONNECTION_INFORMATION_EX lpInBuffer,32 nInBufferSize,ref USB_NODE_CONNECTION_INFORMATION_EX lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet = CharSet.Ansi,SetLastErro
58、r=true)ernal sic externDeviceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_DESCRIPTOR_REQUESTlpInBuffer,32 nInBufferSize,ref USB_DESCRIPTOR_REQUESTlpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);DllImport(kernel32.dll, CharSet= CharSet.Ansi,SetLastError=true)ernal sic externDe
59、viceIoControl(Ptr hFile,32 dwIoControlCode,ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpInBuffer,32 nInBufferSize,ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpOutBuffer,32 nOutBufferSize,out32 lpBytesReturned,Ptr lpOverlapped);#endregionC#:USB 設(shè)備枚舉(二)設(shè)備枚舉 API開發(fā)環(huán)境:Visual Studio V2010.NET Framework 4 Cnt Prof
60、ile版本歷史:V1.02011 年 10 月 10 日基于 WDK 枚舉 USB 設(shè)備*/usingSystem;usingSystem.Collections.Generic;usingSystem.Management;usingSystem.Runtime.eropServi;usingSystem.Text;namespaplash.IO.PORTS/USB 主控制器信息/public struct HostControllerInfopublic String PNPDeviceID;/ 設(shè)備 IDpublic String Name;/ 設(shè)備名稱/ / USB Hub 信息/ p
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 水浪費行為治理專項行動計劃
- 提升水上活動安全監(jiān)管的工作要求計劃
- 幼兒園學(xué)期教研計劃
- 生物知識的區(qū)域性調(diào)查報告計劃
- 學(xué)校秋季多元化學(xué)習(xí)活動計劃
- 前臺文員職業(yè)技能提升計劃
- 秋季區(qū)域聯(lián)盟學(xué)習(xí)計劃
- 提高急救意識的社區(qū)活動計劃
- 教學(xué)銜接與過渡方案計劃
- 項目的角度下的營推廣過程中多種人員互動及其角差發(fā)揮的研究
- VTE防治在臨床科室的落地
- 2025年度個人住房買賣合同(帶家居家具)
- 生產(chǎn)車間布局優(yōu)化與現(xiàn)場改善的策略研究
- 文化自信-最炫中國風(fēng)(2024年內(nèi)蒙古赤峰中考語文試卷非連續(xù)性文本閱讀試題)
- (新版)廣電全媒體運營師資格認證考試復(fù)習(xí)題庫(含答案)
- 2024年法律職業(yè)資格考試(試卷一)客觀題試卷與參考答案
- 安全生產(chǎn)重大事故隱患排查報告表
- 2021年四川省綿陽市中考物理真題及答案
- 小學(xué)音樂課后服務(wù)教學(xué)設(shè)計方案計劃
- 人教版八年級數(shù)學(xué)下冊全冊教案(完整版)教學(xué)設(shè)計
- 電機零部件中英文對照表
評論
0/150
提交評論