project1 - lap trinh pic ket noi giao tiep usb

23
NguyӉn Ngӑc Hѭng Lӟp TKTL 40 HVKTQS - 1 - I NÓI ĈҪU HiӋn nay các thiӃt bӏ USB ngày càng ӭng dөng rӝng rãi, viӋc làm ra các thiӃt bӏ USB ÿang là cҫn thiӃt ÿӕi vӟi tҩt cҧ nhӳng ai hӑc vӅ ÿLӋn tӱ kӇ cҧ các n không hӑc lƭnh vӵc này cNJng rҩt muӕn nҳm bҳt nó. Phҫn lӟn các thiӃt bӏ USB hiӋn nay ÿӅu có sҹn driver cӫa các nha cung cҩp thұm chí có cҧ fimware cho các con chip ÿLӅu khiӇn. Vӟi mөc ÿính tӵ làm ra mӝt thiӃt bӏ USB tӯ A ÿӃn Z (hѫi quá hihi) bao gӗm làm phҫn cӭng, viӃt fimware, tҥo driver, và lұp mӝt giao diӋn trên máy tính ÿӇ giao tiӃp vӟi thiӃt bӏ USB mà ta vӯa tҥo ra, hѭӟng n này giúp cho ngѭӡi hӑc có thӇ làm tҩt cҧ các viӋc ÿó. Ĉһc biӋt là các bҥn sinh viên thì có thӇÿây là viӋc khó khăn, nhѭng hãy chú ý ÿӑc hѭӟng dүn này n có thӇ nҳm bҳt ÿѭӧc nó và thҩy rҵng nó cNJng thұt là ÿѫn giҧn. Chúng ta hãy cùng nhau hӑc tұp, nghiên cӭu ÿӇ giao thӭc USB càng ngày càng trӣ nên thông ng và dӉ hiӇu nhѭ UART vұy…Do ÿó phѭѫng châm khi viӃt bài này là càng ÿѫn giҧn càng tӕt, và chӍ cҫn chú ý ÿӃn nhӳng cái quan trong nhҩt. Hy vӑng sau khi ÿӑc nó tҩt cҧ cá bҥn có thӇ tӵ mình làm ÿѭӧc mӝt Project theo ý muӕn và phát triӇn nó tùy thích. Vӟi kiӃn thӭc còn hҥn chӃ có thӇ hѭӟng dүn này còn nhiӅu hҥn chӃ mong ÿѭӧc sӵ chӍ giáo cӫa tҩt cҧ các bҥn. Thanks! Không có vic gì khó, ch s lòng không bn. Vic gì khó có Sinh viên! Hà nӝi, ngày 18/12/2008 NguyӉn Ngӑc Hѭng

Upload: pham-hoang-anh

Post on 27-Apr-2015

826 views

Category:

Documents


14 download

TRANSCRIPT

Page 1: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 1 -

I NÓI U

Hi n nay các thi t b USB ngày càng ng d ng r ng rãi, vi c làm ra cácthi t b USB ang là c n thi t i v i t t c nh ng ai h c v n t k c các

n không h c l nh v c này c ng r t mu n n m b t nó. Ph n l n các thi t bUSB hi n nay u có s n driver c a các nha cung c p th m chí có c fimwarecho các con chip u khi n. V i m c ính t làm ra m t thi t b USB t A nZ (h i quá hihi) bao g m làm ph n c ng, vi t fimware, t o driver, và l p m tgiao di n trên máy tính giao ti p v i thi t b USB mà ta v a t o ra, h ng

n này giúp cho ng i h c có th làm t t c các vi c ó. c bi t là các b nsinh viên thì có th ây là vi c khó kh n, nh ng hãy chú ý c h ng d n này

n có th n m b t c nó và th y r ng nó c ng th t là n gi n. Chúng ta hãycùng nhau h c t p, nghiên c u giao th c USB càng ngày càng tr nên thông

ng và d hi u nh UART v y…Do ó ph ng châm khi vi t bài này là càngn gi n càng t t, và ch c n chú ý n nh ng cái quan trong nh t. Hy v ng sau

khi c nó t t c cá b n có th t mình làm c m t Project theo ý mu n vàphát tri n nó tùy thích. V i ki n th c còn h n ch có th h ng d n này cònnhi u h n ch mong c s ch giáo c a t t c các b n. Thanks!

Không có vi c gì khó, ch s lòng không b n. Vi c gì khó có Sinh viên!

Hà n i, ngày 18/12/2008 Nguy n Ng c H ng

Page 2: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 2 -

Ph n 1Ph n c ng USB 2.0

1. Các linh ki n chính:- Pic18f4550( ho c Pic18f2550 ).- ng USB ki u B.- Cáp USB 2 u ki u A và B.- Th ch anh có tr s là b i c a 4, t c là có giá tr 4,8,12,16,20(Mhz).- t s linh ki n làm m ch tu ch n.

2. m ch giao ti p n gi n:

ch trên th c t tôi dùng th ch anh 12M t 22p, và có s d ng m chchuy n i n ap dùng Max232 giao ti p UART.

3. u b ng m ch ã thi t k :Vì không có máy nh nên không ch p c hình này.

4. t s chú ý v ph n c ng:- Th ch anh s d ng ph i là các b i c a 4 ví d 4M, 8M, 12M, 20M.

Yêu c u này là do t n s ho t ng c a bus USB là 12Mbs, chipn t o ra t n s 4M t ngu n th nh anh, sau ó dùng nhân t n t i

96M và tùy thu c vào vi c có t bit chia t n c p cho modulUSB và CPU.

- Không nên b qua các t ch ng nhi u chân t, chân ngu n c achíp, t i chân n áp ra c a v-usb.

- Dây cáp USB 2 u nên mua ng b v i c ng USB ki u B vàkhông nên dây cáp quá dài s gây suy gi m tín hi u.

Page 3: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 3 -

- Nên t n d ng ngu n nuôi t c ng USB thay vì ngu n ngoài và bxung thêm m t s t ch ng nhi u, n nh ngu n n u c n.

- Khi làm v i PIC18f2550 tôi th y c n ph i n i tr chân PGM xu ngt thì chip m i ch y??

Vi c ti p theo là vi t fimware cho chip, sau ó t o driver và vi t dao di n th c hi n vi c truy n nh n, t t c các v n ó c c p ph n 2 và ph n 3.Chú ý r ng vi c mô ph ng trên proteus 7.2 ch giúp ta nh n bi t c fimware

a ta vi t ã úng ch a qua vi c PC có phát hi n c thi t b hay không màkhông th dung nó t o driver b ng ph n m m WinDriver, có l do hai ph n

m này không t ng thích nhau.

Page 4: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 1 -

Ph n 2:Vi t Fimware cho Pic18f4550 ( ho c Pic18f2550)

1. Trình biên d ch:Có th vi t Fimware b ng t t c các trình biên d ch thông d ng, song theo ý ki n

a tôi CCS là trình biên d ch h tr vi t Fimware cho chíp USB khá t t. Trongví d c a CCS có các ví d cho c HID, Costume Driver và CDC. ng th i cácth vi n hàm cho USB c xây d ng t ng i thu n l i khi s d ng vì v y r tthu n l i các b n có th nhanh chóng th c hi n USB.

2. Các th c th nghi m:Sau khi ph n c ng ã c u n i y b n có th n p thcác các fimware có s n t ng thích v i ph n c ng và c m thi t b vào máy tính.

u ph n c ng úng và fimware t ng thích máy tính s thông báo “FoundNew Hardware” và òi h i cài t Driver cho thi t b . C n l u ý n u ph n m ntrong chíp cài t t n s th ch anh không kh p v i th ch anh ph n c ng s gâyra l i và máy tính không th nh n di n thi t b . N u khi ã t ng thích v th chanh mà máy tính v n không detect thi t b thì có th ph n c ng c a b n v n còn

n ho c c ng USB có v n v ti p xúc hãy ki m tra k .u thi t b c a b n không b l i và fimware chính xác:

Khi nó òi Driver hãy t m th i b qua và th c hi n t o Driver m i cho nó b ngph n m m WinDriver, khi t o xong Driver thì thi t b s c t ng updatedriver, chi ti t vi c t o driver c h ng d n ph n 3.

3. Các th vi n và hàm s d ng chính vi t USB:Có 3 file b n c n include vào project CCS c a b n là:

- #include <pic18_usb.h>- #include <usb.c>- #include <usb_desc_scope1.h>

Hai file trên có s n trong th vi n c a CCS ch a các nh ngh a và các hàm ph c cho giao ti p USB, file th 3 là file mô t thi t b c ch nh s a t file

usb_desc_scope.h ng có s n trong th vi n c a CCS phù h p v i yêu c ua b n. Ngoài ra còn m t file n a là:

- #include . ng d n/ usb_demo_bulk.h>File này không có s n trong CCS nh các file trên. Nó c t o ra khi b n l p

t Project trên CCS qua PIC Wizard, tên file do b n t.

Page 5: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 2 -

4. Các hàm u khi n và giao ti p USB:Khi xem các mã ngu n c a các file trên trong CCS, b n s th y r t nhi u hàm và

nh ngh a khó hi u. Nh ng ph n l n b n s không c n quan tâm t i các hàm óvì chúng c xây d ng trình biên d ch s d ng. Cái chúng ta quan tâm ch là

p hàm “User Functions” mà CCS ã xây d ng s n:

//// **************** USER FUNCTIONS *********************** //////// //////// usb_init() - Initializes the USB stack, the USB peripheral and //////// attaches the unit to the usb bus. Enables //////// interrupts. //////// //////// usb_init_cs() - A smaller usb_init(), does not attach unit //////// to usb bus or enable interrupts. //////// //////// usb_put_packet() - Sends one packet to the host. //////// If you need to send a message that spans //////// more than one packet then see usb_puts() in //////// usb.c //////// //////// usb_kbhit() - Returns true if OUT endpoint contains data from //////// host. //////// //////// usb_rx_packet_size() - Returns the size of packet that was //////// received. usb_kbhit() must return TRUE else //////// this is not valid. Don't forget in USB there //////// are 0 len packets! //////// //////// usb_get_packet() - Gets one packet that from the host. //////// usb_kbhit() must return true before you call //////// this routine or your data may not be valid. //////// Once usb_kbhit() returns true you want to //////// call this as soon as possible to get data //////// out of the endpoint buffer so the PC can //////// start sending more data, if needed. //////// This only receives one packet, if you are //////// trying to receive a multi-packet message //////// see usb_gets() in usb.c. //////// //////// usb_detach() - De-attach USB from the system. //////// //////// usb_attach() - Attach USB to the system. //////// //////// usb_attached() - Returns TRUE if the device is attached to a //////// USB cable. A macro that looks at the defined //////// connection sense pin. //////// //////// usb_task() - Keeps track of connection sense, calling //////// usb_detach() and usb_attach() when needed. //////// //////// For more documentation on these functions read the comments at ////

Page 6: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 3 -

//// each function. //////// //////// The other functions defined in this file are for use by the //////// USB code, and is not meant to be used by the user. ////

Các b n có th d dàng tìm hi u thêm cách th c s d ng các hàm này qua cácExample và các Comment c a CCS. V i các hàm này b n ã có th u khi nmodul USB c a pic18 khá linh ho t và có th m r ng chúng phù h p v i

c ích c a b n.

5. o l i file mô t thi t b usb_desc_scope1.h c th c hi n nh sau:

#DEFINE USB_TOTAL_CONFIG_LEN 32 //config+interface+class+endpoint

//configuration descriptor char const USB_CONFIG_DESC[] = { //config_descriptor for config index 1 USB_DESC_CONFIG_LEN, //length of descriptor size USB_DESC_CONFIG_TYPE, //constant CONFIGURATION (0x02) USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config 1, //number of interfaces this device supports 0x01, //identifier for this configuration. (IF we had more than oneconfigurations) 0x00, //index of string descriptor for this configuration 0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't),bits 0-4 reserved and bit7=1 0x32, //maximum bus power required (maximum milliamperes/2) (0x32 =100mA)

//interface descriptor 0 alt 0 USB_DESC_INTERFACE_LEN, //length of descriptor USB_DESC_INTERFACE_TYPE, //constant INTERFACE (0x04) 0x00, //number defining this interface (IF we had more than one interface) 0x00, //alternate setting 2, //number of endpoints, not counting endpoint 0. 0xFF, //class code, FF = vendor defined 0xFF, //subclass code, FF = vendor 0xFF, //protocol code, FF = vendor 0x00, //index of string descriptor for interface

//endpoint descriptor USB_DESC_ENDPOINT_LEN, //length of descriptor USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (0x05)

0x81, //endpoint number and direction (0x81 = EP1 IN) 0x02, //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt) USB_EP1_TX_SIZE & 0xFF,USB_EP1_TX_SIZE >> 8, //maximum packet sizesupported 0x01, //polling interval in ms. (for interrupt transfers ONLY)

//endpoint descriptor

Page 7: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 4 -

USB_DESC_ENDPOINT_LEN, //length of descriptor USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (0x05) 0x01, //endpoint number and direction (0x01 = EP1 OUT) 0x02, //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)

USB_EP1_RX_SIZE & 0xFF,USB_EP1_RX_SIZE >> 8, //maximum packet sizesupported 0x01, //polling interval in ms. (for interrupt transfers ONLY)

};

//****** BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ******** //since we can't make pointers to constants in certain pic16s, this is an offset table to find // a specific descriptor in the above table.

//NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUSTSTART AT 0 AND BE SEQUENTIAL // FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BEINTERFACE 0 AND INTERFACE 1 #define USB_NUM_HID_INTERFACES 0

//the maximum number of interfaces seen on any config //for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define thisas 2 #define USB_MAX_NUM_INTERFACES 1

//define how many interfaces there are per config. [0] is the first config, etc. const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1};

#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN) #error USB_TOTAL_CONFIG_LEN not defined correctly #endif

//////////////////////////////////////////////////////////////////////// start device descriptors/////////////////////////////////////////////////////////////////////

//device descriptor char const USB_DEVICE_DESC[] ={ USB_DESC_DEVICE_LEN, //the length of this report 0x01, //constant DEVICE (0x01) 0x10,0x01, //usb version in bcd 0x00, //class code (if 0, interface defines class. FF is vendor defined) 0x00, //subclass code 0x00, //protocol code USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOWSPEED SPECIFIES 8) 0xd8,0x04, //vendor id (0x04D8 is Microchip) 0x01,0x01, //product id 0x00,0x01, //device release number

Page 8: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 5 -

0x01, //index of string description of manufacturer. therefore we point tostring_1 array (see below) 0x02, //index of string descriptor of the product 0x00, //index of string descriptor of serial number USB_NUM_CONFIGURATIONS //number of possible configurations };

//////////////////////////////////////////////////////////////////////// start string descriptors/// String 0 is a special language string, and must be defined. People in U.S.A. can leave thisalone.////// You must define the length else get_next_string_character() will not see the string/// Current code only supports 10 strings (0 thru 9)/////////////////////////////////////////////////////////////////////

//the offset of the starting location of each string.//offset[0] is the start of string 0, offset[1] is the start of string 1, etc.const char USB_STRING_DESC_OFFSET[]={0,4,12};

#define USB_STRING_DESC_COUNT sizeof(USB_STRING_DESC_OFFSET)

char const USB_STRING_DESC[]={ //string 0 4, //length of string index USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) 0x09,0x04, //Microsoft Defined for US-English //string 1 8, //length of string index USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) 'B',0, 'M',0, 'E',0, //string 2 46, //length of string index USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) 'D',0, 'a',0, 'T',0, 'a',0, ' ',0, 'T',0, 'r',0, 'a',0, 'n',0, 's',0, 'f',0, 'e',0, 'r',0,

Page 9: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 6 -

' ',0, 'B',0, 'u',0, 'l',0, 'k',0, ' ',0, 'N',0, 'N',0, 'H',0,};#ENDIF

n không c n ph i ch nh s a gì nhi u trong file này, ch c n l u ý n m t sm mà tôi ã ánh d u b ng màu , t i ó ã có các chú thích b ng ti ng anh

t rõ v ý ngh a c a chúng. ó là s thi t b c h tr giao ti p, s m cu i,vi c kh i t o các ng ng truy n và nh n, c c a gói truy n và ph ng th ctruy n. ây tôi truy n theo lo i BULK. ó là nh ng thông s b n c n quantâm nh ng không c n s a.Các thông s sau là vendor id & product id n có th s a tùy ý mi n là khôngtrùng v i thi t b ã có trong PC c a b n. Cu i cùng là string index n có s a

i theo tên mà b n mong mu n, chú ý r ng chi u dài c a chu i ký t ph i phùp v i khai báo.

Còn m t s khai báo n a nh ng tôi vào trong file khác ti n vi c s a i, cth c trong file usb_demo_bulk.h

6. Qu n lý file usb_demo_bulk.h:Nh ã nói trên file này c t o ra khi ta l p Project trong CCS, bây gi tathêm vào trong ó m t s khai báo:#include <18F4550.h>#device adc=8

#FUSES NOWDT //No Watch Dog Timer#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale#FUSES EC_IO //External clock#FUSES NOPROTECT //Code not protected from reading#FUSES BROWNOUT //Reset when brownout detected#FUSES BORV20 //Brownout reset at 2.0V#FUSES NOPUT //No Power Up Timer#FUSES NOCPD //No EE protection#FUSES STVREN //Stack full/underflow will cause reset#FUSES NODEBUG //No Debug mode for ICD#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOWRT //Program memory not write protected#FUSES NOWRTD //Data EEPROM not write protected#FUSES IESO //Internal External Switch Over mode enabled#FUSES FCMEN //Fail-safe clock monitor enabled#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET#FUSES NOWRTC //configuration not registers write protected#FUSES NOWRTB //Boot block not write protected#FUSES NOEBTR //Memory not protected from table reads

Page 10: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 7 -

#FUSES NOEBTRB //Boot block not protected from table reads#FUSES NOCPB //No Boot Block code protection#FUSES MCLR //Master Clear pin enabled#FUSES LPT1OSC //Timer1 configured for low-power operation#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled#FUSES PLL3 // PLL PreScaler 3#FUSES USBDIV#FUSES VREGEN#FUSES CPUDIV1#FUSES HSPLL

#use delay(clock=12000000)#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#DEFINE USB_HID_DEVICE FALSE#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1 for INbulk/interrupt transfers#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1 for OUTbulk/interrupt transfers#define USB_EP1_TX_SIZE 64 //size to allocate for the tx endpoint 1 buffer#define USB_EP1_RX_SIZE 8 //size to allocate for the rx endpoint 1 buffer

void setup(){ setup_adc_ports(AN0|VSS_VDD); setup_adc(ADC_OFF); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_timer_3(T3_DISABLED|T3_DIV_BY_1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_low_volt_detect(FALSE); setup_oscillator(False);}Nh ng m chú ý tôi ã ánh d u trên, b n c n l u ý r ng t n s th nh anhngoài s c chia c dao ng 4M ây là yêu c u b t bu c khi s d ngPLL. ây tôi dùng th ch anh 12M nên PLL=3. M t s tham s khác b n có thxem chi ti t trong datasheet.Nh v y n ây ta ch còn m t công vi c n a là vi t hàm main. 7. ch ng trình chính:#include "E:\MICROCONTROL\PIC\USB\usb_demo_bulk.h"#include <pic18_usb.h>#include <usb_desc_scope1.h>#include <usb.c>

void usb_debug_task(void){

Page 11: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 8 -

static int8 last_connected; static int8 last_enumerated; int8 new_connected; int8 new_enumerated;

new_connected=usb_attached(); new_enumerated=usb_enumerated();

if (new_connected && !last_connected) printf("\r\n\nUSB connected, waiting for enumaration..."); if (!new_connected && last_connected) printf("\r\n\nUSB disconnected, waiting for connection..."); if (new_enumerated && !last_enumerated) printf("\r\n\nUSB enumerated by PC/HOST"); if (!new_enumerated && last_enumerated) printf("\r\n\nUSB unenumerated by PC/HOST, waiting for enumeration...");

last_connected=new_connected; last_enumerated=new_enumerated;}

void main(){ int8 out_data[2]; int8 in_data[2]; int8 send_timer=0; int8 count=0; int16 i;

setup();

// TODO: USER CODE!! printf("\r\n Transfer BULK Example"); usb_init_cs();

while (TRUE) { usb_task(); usb_debug_task(); if(usb_enumerated()) { if (!send_timer) { count++; send_timer=250; out_data[0]=count; if (usb_put_packet(1, out_data, 1, USB_DTS_TOGGLE)) printf("\r\n<-- Sending 2 bytes: 0x%X", out_data[0]); } if (usb_kbhit(1)) { usb_get_packet(1, in_data, 1);

Page 12: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 9 -

printf("\r\n--> Received data: 0x%X",in_data[0]);; } send_timer--; delay_ms(1); } }

b n ch ng trình trên gi ng v i ví d c a CCS. Trong ch ng trình s d nghàm usb_debug_task() dùng g r i b ng giao ti p UART, n u b n s d nglaptop không có c ng COM thì có th thay chúng b ng vi c hi n th ra LED.Trong ch ng trình chính th c hi n c 250ms thì truy n qua bus USB lên PC giátr count, giá tr này sau m i l n truy n c t ng lên 1, khi n giá tr 0xFF thì

ng tr v 0. Trong ch ng trình còn liên t c ki m tra xem m cu i cónh n c d li u t PC không, n u có thì l y d li u trong b m v bi nin_data. C truy n và nh n u c ki m tra b ng vi c hi n th qua UART. n

ây ta ã hoàn t t vi c vi t fimware cho V K, ây tôi dùng PIC18F4550 vi cvi t ch ng trình cho PIC18f2550 không có gì khác.Chúng ta b t tay vào vi c t o driver cho thi t b và vi t m t ch ng trình giaodi n n gi n b ng C#.

Page 13: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 1 -

Ph n 3:Vi t Ch ng Trình C# giao ti p v i thi t b USB

1. T o Driver cho thi t b và t o các th vi n hàm giao ti p USB:Công vi c u tiên mà b n ph i làm v i WinDriver t o Driver và các

th vi n ph n m m cho ch ng trình PC c a b n. Các b c ti n hành bao g m:

1. n thi t b c a b n vào c ng USB trên máy tính computer:2. Ch y DriverWizard và ch n thi t b c a b n:

hình 1: M ho c t o m t WinDriver ProjectCh n thi t b c a b n trong list c a WinDriver:

Page 14: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 2 -

Ch n phát ra file Driver và ánh tên cho thi t b c a b n:

Ti p t c ch n next ta c:

i ây b n có th ki m tra vi c truy n nh n qua USB xem thi t b c a b n ãho t ng ch a. Vi c ti p theo là t o ra giao di n ban u và th vi n trên C#.Click và bi u t ng Generate Code và ch n ngôn ng mà b n s d ng, hi n nayngôn ng C# thông d ng v i nhi u ng i và có nhi u ti n ích h n so v i VBnên ây tôi ch n nh sau:

Công vi c còn l i ch là OK và ch máy ch y hihi.

Page 15: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 3 -

Ch y Project trên Visual Studio 2005 b n có th th y WinDriver ã t o cho tat giao di n ban u s d ng các giao ti p USB, b n có th s d ng luôn

giao di n này th c hi n theo Project c a b n:

Chú ý r ng b n ph i Project/ Set as Startup Project tr c ã.Nh ng giúp cho ng i m i h c có th hi u c m t cách nhanh chóng tôixin t t o m t giao di n khác n gi n ng n g n h n b ng vi c s d ng các thvi n mà WinDriver v a t o ra cho chúng ta. ó là hai th vi nproject_usb_4550_lib.dll (th vi n này do ta t nó cùng v i tên Project khi t ora) và wdapi_dotnet921.dll hai th viên này ch a các l p và các y quy n r t

u ích giúp cho vi c qu n lý và th c hiên giao ti p b ng USB.

Công vi c ti p theo c a chúng ta là hãy tam quên i cái giao di n mà WinDrivera t o ra trên, và b t tay vào t o m t giao di n c a chính chúng ta. V i

ph ng châm càng n gi n càng t t nên h ng d n này tôi ch t o m t giaodi n ch v i 2 Button và 2 textBox dùng u khi n nh sau:

Page 16: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 4 -

y là song b c u tiên, b c ti p theo là add 2 th vi n trên vào trongproject c a mình và nghiên c u cách s d ng chúng. N u b n add thành công thì

n s th y chúng nh sau:

Ta hãy xem chúng có nh ng gì ( vi c s d ng ch y u trên th vi nproject_usb_4550_lib.dll):

Th vi n này ch a 4 u quy n (delegates) dành t o các s ki n quan tr ngi bus USB và 4 l p, trong ó 3 l p u khi n thi t b USB và m t l p

Page 17: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 5 -

qu n lý danh sách các thi t b USB khác nhau c gán vào PC. Chúng ta hãyquan sát c th h n v i các u quy n và các l p này:- quy n D_USER_ATTACH_CALLBACK d ng gán s ki n cóthi t b USB thích h p g n vào bus USB v i m t hàm callback do b n t o rath ng là kh i t o vi c truy n nh n d li u.- quy n D_USER_DETACH_CALLBACK c s d ng gán ski n thi t b USB ã c tháo ra v i m t hàm g i l i do b n xây d ng th nglà thông báo cho ngu i s d ng v vi c Disconnect và k t thúc vi c truy n nh n- quy n D_USER_TRANSFER_COMPLETION khá h u ích vì nó sgán s ki n truy n nh n k t thúc vào m t hàm x lý c vi t d li u usb do b nxây d ng.- quy n D_USER_POWER_CHANGE_CALLBACK ít c s d ng

n vì nó liên quan n vi c báo ng thay i ngu n trên bus USB, b n có thn d ng th c hi n các bi n pháp b o m c t ngu n bus USB khi có s c .

- p KEY_USB_Device ch a các hàm th c hi n vi c cài t c u hìnhkhác nhau cho thi t b USB hay hàm c các s hi u VP, IP và hàm theo dõitr ng thái truy n nh n c a thi t b :

- p KEY_USB_DeviceManager th c hi n vi c qu n lý thi t b USB và s l ng thi t b USB c g n vào:

- p KEY_USB_Pipe có s l ng hàm t ng i l n và chuyên d ng c vi t d li u ki m tra tr ng thái truy n nh n, ki m soát vi c kh i ng vàng các ng ng…

- L p Pipe_list th c hi n qu n lý các ng ng vào ra c a thi t b .p các hàm này khá linh ho t và y cho m i ng d ng USB và b n c ng

không c n ph i tìm hi u k t t c các hàm ó vì chúng ta ch c n làm vi c v it s hàm nh t nh là giao ti p.

Bây gi là n công vi c khó nh t ây, ta ph i vi t code làm sao cho khi g nthi t b vào thì nó ph i nh n c và th c hi n truy n phát d li u.

Page 18: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 6 -

Ý t ng c a tôi là dùng Button1(tên là btwrite) th c hi n vi c truy n d li uc l y trong textBox1(tên là txttrans) t PC xu ng V K, Button2(btread)

dùng l y d li u t V K lên PC hi n th textBox2(txtLog). thu t toán th c hi n ch ng trình chúng ta ch h n ch 3 ch c n ng c b n

là c, vi t d li u và phát hi n thi t b gán vào hay tháo ra (hai s ki n nh nbi t thi t b u c hi n th trên txtLog).Ph n khai báo USING c a ch ng trình chúng ta c n m t 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 d ng th vi n wdapi_dotnetusing Jungo.project_usb_4550_lib; //s d ng th vi n project_usb_4550_libusing wdu_err=Jungo.wdapi_dotnet.WD_ERROR_CODES;//s d ng vi c khai báo l i

using DWORD = System.UInt32;using WORD = System.UInt16;using UCHAR = System.Byte;

ph n khai báo các bi n c a form chính chúng ta th c hi n m t s khai báo hàngbi n và t o các i t ng 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 accordinglyprivate 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 kh i t ovi c qu n lý i t ng USBprivate PROJECT_USB_4550_Device usb_device; //khai báo i t ng USBprivate PROJECT_USB_4550_Pipe usb_pipe_trs; //khai báo i t ng ng truy nprivate PROJECT_USB_4550_Pipe usb_pipe_rev; //khai báo i t ng ng nh nprivate delegate void D_ATTACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);//khai báo y quy n thông báo thi t b g n vàoprivate delegate void D_DETACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);//khai báo y quy n thông báo thi t b tháo radelegate void safeLogTextCallBack(string sMsg); //khai báo y quy n ph c vhi n th

Chúng ta ã có 1 i t ng qu n lý USB, 1 i t ng thi t b USB, 2 i t ngng ng TRANSFER và RECEIVER, các k t n i, khai báo driver u khi n

và các u quy n c n thi t. Ti p theo chúng ta s xây d ng các hàm c a formtheo các s ki n chính. S ki n u tiên chúng ta c n quan tâm là “form load”vì nó x y ra u tiên trong chu i s ki n vì v y có th t n d ng kh i t o m t

bi n, i t ng cho ch ng trình.

private void form_main_Load(object sender, EventArgs e) {

// ng ký hai hàm s ki n ATTACH_CALLBACK & DETACH_CALLBACK

Page 19: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 7 -

D_USER_ATTACH_CALLBACK dDeviceAttachCb = newD_USER_ATTACH_CALLBACK(UserDeviceAttach);

D_USER_DETACH_CALLBACK dDeviceDetachCb = newD_USER_DETACH_CALLBACK(UserDeviceDetach);

//kh i t o i t ng qu n lý thi t b USB uDevManager = newPROJECT_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 ki n Attacth và Detach theo c c u trung gian ci n 2 hàm UserDeviceAttach & UserDeviceDetach kh i t o các ing AttachCb và DetachCb . Trong hàm này còn th c hi n vi c kh i t o thi t b

USB và hai ng ng TRANSFER & RECEIVER.private void UserDeviceAttach(PROJECT_USB_4550_Device pDev) {

D_ATTACH_GUI_CALLBACK AttachCb = newD_ATTACH_GUI_CALLBACK(DeviceAttachGuiCb);

// kh i t o thi t b USB usb_device = pDev;

// kh i t o ng ng nh n và truy n 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 = newD_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);

Invoke(DetachCb, new object[] { pDev }); }

Các hàm DeviceAttachGuiCb & DeviceDetachGuiCb ch là các hàm hi n th tr ngthái thi t b g n 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"); }

thu n l i cho vi c hi n th tr ng thái ch ng trình chúng ta nên b xung m t hàm u khi n vi c xu t thông báo ví d 3 hàm d i â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)

{

Page 20: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 8 -

safeLogTextCallBack cb = newsafeLogTextCallBack(SafeLogText);

this.Invoke(cb, new object[] { sMsg }); }

else { txtLog.AppendText(sMsg); } }

public void TraceMsg(string sMsg) { SafeLogText(sMsg); }

Bây gi ta b t tay vào vi c xây d ng hàm dùng truy n nh n d li u. Khi nh nvào button write thì th c hi n truy n m t byte xu ng V K:private void btwrite_Click(object sender, EventArgs e) { SingleTransfer(); }

Hàm SingleTransfer(); th c hi n vi t s l y 1 byte ã nh p vào txttrans vàchuy n sang d ng byte trong buffer sau ó g i hàm truy n không ng b :usb_pipe_trs.UsbPipeTransferAsync(false, 0, buffer, dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_trs_Completion));

Khi nh n vào button read thì th c hi n nh n m t byte t V K lên PC và hi nth ra txtLog.private void btread_Click(object sender, EventArgs e) { SingleReceiver(); }

Hàm SingleReceiver(); t ng t nh hàm SingleTransfer(); th c hi n vi cnh n d li u vào b m:usb_pipe_rev.UsbPipeTransferAsync(true, 0, buffer, dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_rev_Completion));

Các hàm Transfer_trs_Completion & Transfer_rev_Completion th c hi n vi cthông báo hoàn thành truy n ho c nh n. Hàm DisplayHexBuffer h tr vi chi n th giá tr thâp l c phân.Sau ây là toàn b mã c a ch ng 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;

Page 21: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p 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_deviceprivate 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 = newD_USER_ATTACH_CALLBACK(UserDeviceAttach);

D_USER_DETACH_CALLBACK dDeviceDetachCb = newD_USER_DETACH_CALLBACK(UserDeviceDetach);

uDevManager = newPROJECT_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 = newD_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 = newD_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);

Invoke(DetachCb, new object[] { pDev }); }

Page 22: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p 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, newD_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,

Page 23: Project1 - Lap Trinh PIC Ket Noi Giao Tiep USB

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 11 -

dwBuffSize, TIME_OUT, newD_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;

} }}