Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 1 -
Phn 3:
Vit Chng Trình C# giao tip vi thit b USB
1. To Driver cho thit b và to các th vin hàm giao tip USB:
Công vic u tiên mà bn phi làm vi WinDriver to Driver và các
th vin phn mm cho chng trình PC ca bn. Các bc tin hành bao gm:
1. n thit b ca bn vào cng USB trên máy tính computer:
2. Chy DriverWizard và chn thit b ca bn:
hình 1: M hoc to mt WinDriver Project
Chn thit b ca bn trong list ca WinDriver:
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 2 -
Chn phát ra file Driver và ánh tên cho thit b ca bn:
Tip tc chn next ta c:
i ây bn có th kim tra vic truyn nhn qua USB xem thit b ca bn ã
hot ng cha. Vic tip theo là to ra giao din ban u và th vin trên C#.
Click và biu tng Generate Code và chn ngôn ng mà bn s dng, hin nay
ngôn ng C# thông dng vi nhiu ngi và có nhiu tin ích hn so vi VB
nên ây tôi chn nh sau:
Công vic còn li ch là OK và ch máy chy hihi.
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 3 -
Chy Project trên Visual Studio 2005 bn có th thy WinDriver ã to cho ta
t giao din ban u s dng các giao tip USB, bn có th s dng luôn
giao din này thc hin theo Project ca bn:
Chú ý rng bn phi Project/ Set as Startup Project trc ã.
Nhng giúp cho ngi mi hc có th hiu c mt cách nhanh chóng tôi
xin t to mt giao din khác n gin ngn gn hn bng vic s dng các th
vin mà WinDriver va to ra cho chúng ta. ó là hai th vin
project_usb_4550_lib.dll (th vin này do ta t nó cùng vi tên Project khi to
ra) và wdapi_dotnet921.dll hai th viên này cha các lp và các y quyn rt
u ích giúp cho vic qun lý và thc hiên giao tip bng USB.
Công vic tip theo ca chúng ta là hãy tam quên i cái giao din mà WinDriver
a to ra trên, và bt tay vào to mt giao din ca chính chúng ta. Vi
phng châm càng n gin càng tt nên hng dn này tôi ch to mt giao
din ch vi 2 Button và 2 textBox dùng u khin nh sau:
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 4 -
y là song bc u tiên, bc tip theo là add 2 th vin trên vào trong
project ca mình và nghiên cu cách s dng chúng. Nu bn add thành công thì
n s thy chúng nh sau:
Ta hãy xem chúng có nhng gì ( vic s dng ch yu trên th vin
project_usb_4550_lib.dll):
Th vin này cha 4 u quyn (delegates) dành to các s kin quan trng
i bus USB và 4 lp, trong ó 3 lp u khin thit b USB và mt lp
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 5 -
qun lý danh sách các thit b USB khác nhau c gán vào PC. Chúng ta hãy
quan sát c th hn vi các u quyn và các lp này:
- quyn D_USER_ATTACH_CALLBACK dng gán s kin có
thit b USB thích hp gn vào bus USB vi mt hàm callback do bn to ra
thng là khi to vic truyn nhn d liu.
- quyn D_USER_DETACH_CALLBACK c s dng gán s
kin thit b USB ã c tháo ra vi mt hàm gi li do bn xây dng thng
là thông báo cho ngui s dng v vic Disconnect và kt thúc vic truyn nhn
- quyn D_USER_TRANSFER_COMPLETION khá hu ích vì nó s
gán s kin truyn nhn kt thúc vào mt hàm x lý c vit d liu usb do bn
xây dng.
- quyn D_USER_POWER_CHANGE_CALLBACK ít c s dng
n vì nó liên quan n vic báo ng thay i ngun trên bus USB, bn có th
n dng thc hin các bin pháp bo m ct ngun bus USB khi có s c.
- p KEY_USB_Device cha các hàm thc hin vic cài t cu hình
khác nhau cho thit b USB hay hàm c các s hiu VP, IP và hàm theo dõi
trng thái truyn nhn ca thit b:
- p KEY_USB_DeviceManager thc hin vic qun lý thit b USB và
s lng thit b USB c gn vào:
- p KEY_USB_Pipe có s lng hàm tng i ln và chuyên dng
c vit d liu kim tra trng thái truyn nhn, kim soát vic khi ng và
ng các ng ng…
- Lp Pipe_list thc hin qun lý các ng ng vào ra ca thit b.
p các hàm này khá linh hot và y cho mi ng dng USB và bn cng
không cn phi tìm hiu k tt c các hàm ó vì chúng ta ch cn làm vic vi
t s hàm nht nh là giao tip.
Bây gi là n công vic khó nht ây, ta phi vit code làm sao cho khi gn
thit b vào thì nó phi nhn c và thc hin truyn phát d liu.
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 6 -
Ý tng ca tôi là dùng Button1(tên là btwrite) thc hin vic truyn d liu
c ly trong textBox1(tên là txttrans) t PC xung VK, Button2(btread)
dùng ly d liu t VK lên PC hin th textBox2(txtLog).
thut toán thc hin chng trình chúng ta ch hn ch 3 chc nng c bn
là c, vit d liu và phát hin thit b gán vào hay tháo ra (hai s kin nhn
bit thit bu c hin th trên txtLog).
Phn khai báo USING ca chng trình chúng ta cn mt s khai báo nh sau:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Jungo.wdapi_dotnet; //s dng th vin wdapi_dotnet
using Jungo.project_usb_4550_lib; //s dng th vin project_usb_4550_lib
using wdu_err=Jungo.wdapi_dotnet.WD_ERROR_CODES;//s dng vic khai báo li
using DWORD = System.UInt32;
using WORD = System.UInt16;
using UCHAR = System.Byte;
phn khai báo các bin ca form chính chúng ta thc hin mt s khai báo hàng
bin và to các i tng sau:
private const string DEFAULT_LICENSE_STRING =
"6C3CC2CFE89E7AD04238DF2EF24449E848CDC187.NguyenNgocHung";
// TODO: If you have renamed the WinDriver kernel module (windrvr6.sys),
// change the driver name below accordingly
private const string DEFAULT_DRIVER_NAME = "windrvr6";
private const WORD DEFAULT_VENDOR_ID = 0x04D8;
private const WORD DEFAULT_PRODUCT_ID = 0x0101;
public const DWORD TIME_OUT = 30000;
private PROJECT_USB_4550_DeviceManager uDevManager; //khai báo khi to
vic qun lý i tng USB
private PROJECT_USB_4550_Device usb_device; //khai báo i tng USB
private PROJECT_USB_4550_Pipe usb_pipe_trs; //khai báo i tng ng truyn
private PROJECT_USB_4550_Pipe usb_pipe_rev; //khai báo i tng ng nhn
private delegate void D_ATTACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);
//khai báo y quyn thông báo thit b gn vào
private delegate void D_DETACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);
//khai báo y quyn thông báo thit b tháo ra
delegate void safeLogTextCallBack(string sMsg); //khai báo y quyn phc v
hin th
Chúng ta ã có 1 i tng qun lý USB, 1 i tng thit b USB, 2 i tng
ng ng TRANSFER và RECEIVER, các kt ni, khai báo driver u khin
và các u quyn cn thit. Tip theo chúng ta s xây dng các hàm ca form
theo các s kin chính. S kin u tiên chúng ta cn quan tâm là “form load”
vì nó xy ra u tiên trong chui s kin vì vy có th tn dng khi to mt
bin, i tng cho chng trình.
private void form_main_Load(object sender, EventArgs e)
{
// ng ký hai hàm s kin ATTACH_CALLBACK & DETACH_CALLBACK
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 7 -
D_USER_ATTACH_CALLBACK dDeviceAttachCb = new
D_USER_ATTACH_CALLBACK(UserDeviceAttach);
D_USER_DETACH_CALLBACK dDeviceDetachCb = new
D_USER_DETACH_CALLBACK(UserDeviceDetach);
//khi to i tng qun lý thit b USB
uDevManager = new
PROJECT_USB_4550_DeviceManager(dDeviceAttachCb, dDeviceDetachCb,
DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, DEFAULT_DRIVER_NAME,
DEFAULT_LICENSE_STRING);
}
Hàm 2 callback x lý 2 s kin Attacth và Detach theo c cu trung gian c
i n 2 hàm UserDeviceAttach & UserDeviceDetach khi to các i
ng AttachCb và DetachCb . Trong hàm này còn thc hin vic khi to thit b
USB và hai ng ng TRANSFER & RECEIVER.
private void UserDeviceAttach(PROJECT_USB_4550_Device pDev)
{
D_ATTACH_GUI_CALLBACK AttachCb = new
D_ATTACH_GUI_CALLBACK(DeviceAttachGuiCb);
// khi to thit b USB
usb_device = pDev;
// khi to ng ng nhn và truyn
usb_pipe_rev =
(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[1];
usb_pipe_trs =
(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[2];
Invoke(AttachCb, new object[] {pDev});
}
Và:
private void UserDeviceDetach(PROJECT_USB_4550_Device pDev)
{
D_DETACH_GUI_CALLBACK DetachCb = new
D_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);
Invoke(DetachCb, new object[] { pDev });
}
Các hàm DeviceAttachGuiCb & DeviceDetachGuiCb ch là các hàm hin th trng
thái thit b gn vào hay tháo ra.
private void DeviceAttachGuiCb(PROJECT_USB_4550_Device pDev)
{
TraceMsg("Found new device\r\n");
TraceMsg("Your new device is installed and ready to use\r\n");
}
private void DeviceDetachGuiCb(PROJECT_USB_4550_Device pDev)
{
TraceMsg("Your device has detached\r\n");
}
thun li cho vic hin th trng thái chng trình chúng ta nên b xung mt
hàm u khin vic xut thông báo ví d 3 hàm di ây:
private void SafeLogText(string sMsg)
{
// InvokeRequired compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (txtLog.InvokeRequired)
{
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 8 -
safeLogTextCallBack cb = new
safeLogTextCallBack(SafeLogText);
this.Invoke(cb, new object[] { sMsg });
}
else
{
txtLog.AppendText(sMsg);
}
}
public void TraceMsg(string sMsg)
{
SafeLogText(sMsg);
}
Bây gi ta bt tay vào vic xây dng hàm dùng truyn nhn d liu. Khi nhn
vào button write thì thc hin truyn mt byte xung VK:
private void btwrite_Click(object sender, EventArgs e)
{
SingleTransfer();
}
Hàm SingleTransfer(); thc hin vit s ly 1 byte ã nhp vào txttrans và
chuyn sang dng byte trong buffer sau ó gi hàm truyn không ng b:
usb_pipe_trs.UsbPipeTransferAsync(false, 0, buffer,
dwBuffSize, TIME_OUT, new
D_USER_TRANSFER_COMPLETION(Transfer_trs_Completion));
Khi nhn vào button read thì thc hin nhn mt byte t VK lên PC và hin
th ra txtLog.
private void btread_Click(object sender, EventArgs e)
{
SingleReceiver();
}
Hàm SingleReceiver(); tng t nh hàm SingleTransfer(); thc hin vic
nhn d liu vào bm:
usb_pipe_rev.UsbPipeTransferAsync(true, 0, buffer,
dwBuffSize, TIME_OUT, new
D_USER_TRANSFER_COMPLETION(Transfer_rev_Completion));
Các hàm Transfer_trs_Completion & Transfer_rev_Completion thc hin vic
thông báo hoàn thành truyn hoc nhn. Hàm DisplayHexBuffer h tr vic
hin th giá tr thâp lc phân.
Sau ây là toàn b mã ca chng trình:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Jungo.wdapi_dotnet;
using Jungo.project_usb_4550_lib;
using wdu_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;
using DWORD = System.UInt32;
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 9 -
using WORD = System.UInt16;
using UCHAR = System.Byte;
namespace project_usb_4550
{
public partial class form_main : Form
{
private const string DEFAULT_LICENSE_STRING =
"6C3CC2CFE89E7AD04238DF2EF24449E848CDC187.NguyenNgocHung";
private const string DEFAULT_DRIVER_NAME = "windrvr6";
private const WORD DEFAULT_VENDOR_ID = 0x04D8;
private const WORD DEFAULT_PRODUCT_ID = 0x0101;
public const DWORD TIME_OUT = 30000;
private PROJECT_USB_4550_DeviceManager uDevManager;
private PROJECT_USB_4550_Device usb_device
private PROJECT_USB_4550_Pipe usb_pipe_trs;
private PROJECT_USB_4550_Pipe usb_pipe_rev;
private delegate void D_ATTACH_GUI_CALLBACK(PROJECT_USB_4550_Device
pDev);
private delegate void D_DETACH_GUI_CALLBACK(PROJECT_USB_4550_Device
pDev);
delegate void safeLogTextCallBack(string sMsg);
public form_main()
{
InitializeComponent();
}
private void form_main_Load(object sender, EventArgs e)
{
D_USER_ATTACH_CALLBACK dDeviceAttachCb = new
D_USER_ATTACH_CALLBACK(UserDeviceAttach);
D_USER_DETACH_CALLBACK dDeviceDetachCb = new
D_USER_DETACH_CALLBACK(UserDeviceDetach);
uDevManager = new
PROJECT_USB_4550_DeviceManager(dDeviceAttachCb, dDeviceDetachCb,
DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, DEFAULT_DRIVER_NAME,
DEFAULT_LICENSE_STRING);
}
private void UserDeviceAttach(PROJECT_USB_4550_Device pDev)
{
D_ATTACH_GUI_CALLBACK AttachCb = new
D_ATTACH_GUI_CALLBACK(DeviceAttachGuiCb);
usb_device = pDev;
usb_pipe_rev =
(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[1];
usb_pipe_trs =
(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[2];
Invoke(AttachCb, new object[] {pDev});
}
private void DeviceAttachGuiCb(PROJECT_USB_4550_Device pDev)
{
TraceMsg("Found new device\r\n");
TraceMsg("Your new device is installed and ready to use\r\n");
}
private void UserDeviceDetach(PROJECT_USB_4550_Device pDev)
{
D_DETACH_GUI_CALLBACK DetachCb = new
D_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);
Invoke(DetachCb, new object[] { pDev });
}
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 10 -
private void DeviceDetachGuiCb(PROJECT_USB_4550_Device pDev)
{
TraceMsg("Your device has detached\r\n");
}
private void SafeLogText(string sMsg)
{
// InvokeRequired compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (txtLog.InvokeRequired)
{
safeLogTextCallBack cb = new
safeLogTextCallBack(SafeLogText);
this.Invoke(cb, new object[] { sMsg });
}
else
{
txtLog.AppendText(sMsg);
}
}
public void TraceMsg(string sMsg)
{
SafeLogText(sMsg);
}
private void btwrite_Click(object sender, EventArgs e)
{
SingleTransfer();
}
private void SingleTransfer()
{
DWORD dwBuffSize = 1;
byte[] buffer = new byte[1];
string txt = txttrans.Text;
buffer[0] = Convert.ToByte(txt[0]);
usb_pipe_trs.UsbPipeTransferAsync(false, 0, buffer,
dwBuffSize, TIME_OUT, new
D_USER_TRANSFER_COMPLETION(Transfer_trs_Completion));
}
private void Transfer_trs_Completion(PROJECT_USB_4550_Pipe pipe)
{
if (pipe.GetTransferStatus() ==
(DWORD)wdu_err.WD_STATUS_SUCCESS)
{
TraceMsg("Transfer completed successfully!\r\n ");
}
else
{
TraceMsg("tranfer fail\r\n");
}
}
private void btread_Click(object sender, EventArgs e)
{
SingleReceiver();
}
private void SingleReceiver()
{
DWORD dwBuffSize = 1;
byte[] buffer = new byte[1];
usb_pipe_rev.UsbPipeTransferAsync(true, 0, buffer,
Nguyn Ngc Hng Lp TKTL 40 HVKTQS
- 11 -
dwBuffSize, TIME_OUT, new
D_USER_TRANSFER_COMPLETION(Transfer_rev_Completion));
}
private void Transfer_rev_Completion(PROJECT_USB_4550_Pipe pipe)
{
if (pipe.GetTransferStatus() ==
(DWORD)wdu_err.WD_STATUS_SUCCESS)
{
TraceMsg(DisplayHexBuffer(pipe.GetBuffer(),1));
}
else
{
TraceMsg("receiver failure!\r\n");
}
}
private string DisplayHexBuffer(byte[] buff, DWORD dwBuffSize)
{
string display = "";
for (DWORD i = 0; i < dwBuffSize; i++)
display = string.Concat(display, buff[i].ToString("X")," ");
display = string.Concat(display, Environment.NewLine);
return display;
}
}
}