網站導航:首頁開源項目 USB開源項目:Easy USB 51 Programer  

目錄導航

   
  1、項目簡介
USB開發基礎
1、USB接口的優點及開發難易度
2、USB設備的開發流程
3、USB接口芯片(USB控制器)的選擇
4、了解USB的通訊過程
5、USB命令(請求)和USB描述符
6、實例講解USB的枚舉(配置)過程
准備工作
1、需要哪些工具
2、電路原理圖
3、手工制作您的電路板
4、測試您的硬件
HID設備類
1、讓PC機找到我們的硬件
2、如何成爲一個HID設備(模擬鼠標)
3、如何成爲一個HID設備(模擬鍵盤)
4、如何與HID設備通訊(一)
5、如何與HID設備通訊(二)
6、51編程器的實現
Windows USB 驱动程序(自定义设备)
1、Windows驅動開發基礎
2、開發環境配置
3、第一个实例-Hello Wdm(一)
4、第一个实例-Hello Wdm(二)
5、真正的實例—驅動我們的實驗板
6、真正的實例—測試驅動程序
7、真正的實例—控制LED及讀取按鍵狀態
8、如何編寫應用程序
   

相关産品    淘寶網店
     
 

 
  更多...  
 
 
真正的實例—控制LED及讀取按鍵狀態 查看/参与此開源項目相关讨论
 

1、完善下位機程序

  1)修改Chap_9.c文件中的control_handler函數,內容如下:

 
  1. /*************************************************************  
  2. ** 函數名稱: void control_handler(void)  
  3. ** 功能描述: 控制傳輸  
  4. **************************************************************/  
  5. void control_handler(void)   
  6. {   
  7.     INT8U type, req;   
  8.     INT16U  wValue;   
  9.        
  10.   
  11.     type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;    
  12.                                                 //讀取請求代碼   
  13.     req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;   
  14.        
  15.     wValue = ControlData.DeviceRequest.wValue;   
  16.        
  17.     if (type == USB_STANDARD_REQUEST)   
  18.         (*StandardDeviceRequest[req])();        //標准請求處理   
  19.     else if (type == USB_VENDOR_REQUEST)        //廠商請求   
  20.         (*VendorDeviceRequest[req])(wValue);   
  21.     //else if(type == USB_CLASS_REQUEST)   
  22.     //  (*ClassDeviceRequest[req])();           //類請求,如大容量類   
  23.     else  
  24.         stall_ep0();                            //無效請求,返回STALL                 
  25. }   

  2)在Chap_9.c文件中增加以下函數:

 
  1. sbit K1 = P3^5;   
  2. sbit K2 = P3^6;   
  3.   
  4. /****************************************  
  5. ** 函數名稱: void control_led(INT16U wValue)  
  6. ** 功能描述: 控制擴展板EXT-BOARD-A上的LED  
  7. ** 參    數:INT16U wValue->控制值,低字節有效,如wValue爲0x0000時LED全滅,wValue爲0x00FF時LED全亮  
  8. *****************************************/  
  9. void control_led(INT16U wValue)   
  10. {   
  11.     P0 =    wValue % 256;       //返回一個空的數據表示執行完畢   
  12.        
  13.     single_transmit(0, 0);      //返回一個空的數據表示執行完畢   
  14. }   
  15.   
  16. /****************************************  
  17. ** 函數名稱: void get_key_state(INT16U wValue)  
  18. ** 功能描述: 取得擴展板EXT-BOARD-A上按鍵狀態  
  19. ** 參    數:INT16U wValue->無意義  
  20. *****************************************/  
  21. void get_key_state(INT16U wValue)   
  22. {   
  23.     INT8U ucKeyState[1],i;     
  24.        
  25.     ucKeyState[0]   = 0x00;    
  26.     K1  = 1;   
  27.     K2  = 1;   
  28.     for(i=0;i<100;i++);   
  29.        
  30.     if(~K1) //K1按下   
  31.     {   
  32.         ucKeyState[0]   |= 0x01;   
  33.     }   
  34.        
  35.     if(~K2) //K2按下   
  36.     {   
  37.         ucKeyState[0]   |= 0x02;   
  38.     }   
  39.            
  40.     single_transmit(ucKeyState,1);   
  41. }   
  42.   
  43. //USB廠商請求入口地址指針表   
  44. code void (*VendorDeviceRequest[]) (INT16U wValue) =   
  45. {   
  46.     control_led,   
  47.     get_key_state      
  48. };   

  3)向Chap_9.h中增加以下內容

 
  1. extern code void (*VendorDeviceRequest[])(INT16U wValue);   
  2. extern void control_led(INT16U wValue);   
  3. extern void get_key_state(INT16U wValue);   

下載修改好後的源代碼

2、修改Windows驅動程序

  1)完善IOCTL_LED_Handler函數,內容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. //  Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler   
  3. //   
  4. //  Routine Description:   
  5. //      Handler for IO Control Code IOCTL_LED   
  6. //   
  7. //  Parameters:   
  8. //      I - IRP containing IOCTL request   
  9. //   
  10. //  Return Value:   
  11. //      NTSTATUS - Status code indicating success or failure   
  12. //   
  13. //  Comments:   
  14. //      This routine implements the IOCTL_LED function.   
  15. //      This routine runs at passive level.   
  16. //   
  17.   
  18. NTSTATUS Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler(KIrp I)   
  19. {   
  20.     NTSTATUS status = STATUS_SUCCESS;   
  21.   
  22.     t << "Entering Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler, " << I << EOL;   
  23.     // TODO:    Verify that the input parameters are correct   
  24.     //          If not, return STATUS_INVALID_PARAMETER   
  25.     //檢查輸入參數是否正確,如果不正確,返回 STATUS_INVALID_PARAMETER    
  26.     if(I.IoctlOutputBufferSize() || !I.IoctlBuffer())    
  27.     {   
  28.         status  = STATUS_INVALID_PARAMETER;   
  29.         return status;    
  30.     }   
  31.        
  32.     // TODO:    Handle the the IOCTL_LED request, or    
  33.     //          defer the processing of the IRP (i.e. by queuing) and set   
  34.     //          status to STATUS_PENDING.   
  35.     //處理 IOCTL_LED請求    
  36.     PURB pUrb = m_Lower.BuildVendorRequest(NULL, // 傳輸緩沖區    
  37.         0, //  傳輸緩沖區大小    
  38.         0, //  請求保留位    
  39.         CMD_CTL_LED, //廠商請求代码值,定义:#define CMD_CTL_LED 0x00   
  40.         (UCHAR)(*(PUCHAR)I.IoctlBuffer()),  //控制LED的值,爲0x00時代表全滅,爲0xFF時代表全亮   
  41.         FALSE,       // bIn    
  42.         TRUE,       // bShortOk    
  43.         NULL,       // Link    
  44.         0        // Index    
  45.         );    
  46.   
  47.     if(pUrb)   
  48.     {   
  49.         //向下傳送URB    
  50.         status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 1000L);   
  51.     }   
  52.     else  
  53.     {   
  54.         status  = STATUS_PENDING;   
  55.     }   
  56.   
  57.     delete pUrb;   
  58. // TODO:    Assuming that the request was handled here. Set I.Information   
  59. //          to indicate how much data to copy back to the user.   
  60.     if(NT_SUCCESS(status))     
  61.     {    
  62.         I.Information() = pUrb->UrbControlVendorClassRequest.TransferBufferLength;    
  63.     }    
  64.     else  
  65.     {   
  66.         I.Information() = 0;   
  67.     }   
  68.        
  69.     I.Status()      = status;   
  70.   
  71.     return status;   
  72. }   

  2)完善IOCTL_GET_KEY_Handler函數,內容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. //  Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler   
  3. //   
  4. //  Routine Description:   
  5. //      Handler for IO Control Code IOCTL_GET_KEY   
  6. //   
  7. //  Parameters:   
  8. //      I - IRP containing IOCTL request   
  9. //   
  10. //  Return Value:   
  11. //      NTSTATUS - Status code indicating success or failure   
  12. //   
  13. //  Comments:   
  14. //      This routine implements the IOCTL_GET_KEY function.   
  15. //      This routine runs at passive level.   
  16. //   
  17.   
  18. NTSTATUS Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler(KIrp I)   
  19. {   
  20.     NTSTATUS status = STATUS_SUCCESS;   
  21.   
  22.     t << "Entering Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler, " << I << EOL;   
  23. // TODO:    Verify that the input parameters are correct   
  24. //          If not, return STATUS_INVALID_PARAMETER   
  25.   
  26. // TODO:    Handle the the IOCTL_GET_KEY request, or    
  27. //          defer the processing of the IRP (i.e. by queuing) and set   
  28. //          status to STATUS_PENDING.   
  29.         //處理 IOCTL_LED請求    
  30.     PURB pUrb = m_Lower.BuildVendorRequest((PUCHAR)I.IoctlBuffer(), // 傳輸緩沖區    
  31.         1, //  傳輸緩沖區大小    
  32.         0, //  請求保留位    
  33.         CMD_GET_KEY_STATUS, //廠商請求代码值,定义:#define CMD_GET_KEY_STATUS 0x01   
  34.         0,   
  35.         TRUE,       // bIn    
  36.         TRUE,       // bShortOk    
  37.         NULL,       // Link    
  38.         0        // Index    
  39.         );    
  40.   
  41.     if(pUrb)   
  42.     {   
  43.         //向下傳送URB    
  44.         status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 1000L);   
  45.     }   
  46.     else  
  47.     {   
  48.         status  = STATUS_PENDING;   
  49.     }   
  50.   
  51.     delete pUrb;   
  52.   
  53. // TODO:    Assuming that the request was handled here. Set I.Information   
  54. //          to indicate how much data to copy back to the user.   
  55.     if(NT_SUCCESS(status))     
  56.     {    
  57.         I.Information() = pUrb->UrbControlVendorClassRequest.TransferBufferLength;    
  58.     }    
  59.     else  
  60.     {   
  61.         I.Information() = 0;   
  62.     }   
  63.        
  64.     I.Status()      = status;   
  65.   
  66.     return status;   
  67. }   

  3)在Easy_USB_51_ProgramerDevice.h中加入如下宏定義:

 
  1. #define CMD_CTL_LED 0x00   
  2. #define CMD_GET_KEY_STATUS 0x01   

3、修改測試程序

  1)完善Test_IOCTL_LED函數,內容如下:

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. // Test_IOCTL_LED   
  3. //   
  4. //      Test one Io Control Code   
  5. //   
  6. // TODO:   
  7. //      Pass appropriate arguments to your device and check   
  8. //      the return value   
  9. //   
  10. void Test_IOCTL_LED(void)   
  11. {   
  12. // Note that Input and Output are named from the point of view   
  13. // of the DEVICE:   
  14. //      bufInput  supplies data to the device   
  15. //      bufOutput is written by the device to return data to this application   
  16.   
  17.     CHAR    bufInput[IOCTL_INBUF_SIZE];     // Input to device   
  18.     CHAR    bufOutput[IOCTL_OUTBUF_SIZE];   // Output from device   
  19.     ULONG   nOutput;                        // Count written to bufOutput   
  20.   
  21.     bufInput[0] = 0x03;   
  22.   
  23.     // Call device IO Control interface (IOCTL_LED) in driver   
  24.     printf("Issuing Ioctl to device - ");   
  25.     if (!DeviceIoControl(hDevice,   
  26.                          IOCTL_LED,   
  27.                          bufInput,   
  28.                          IOCTL_INBUF_SIZE,   
  29.                          NULL,   
  30.                          0,   
  31.                          NULL,   
  32.                          NULL)   
  33.        )   
  34.     {   
  35.         printf("ERROR: DeviceIoControl returns %0x.", GetLastError());   
  36.         Exit(1);   
  37.     }   
  38. }   

  2)完善Test_IOCTL_GET_KEY函數,內容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. // Test_IOCTL_GET_KEY   
  3. //   
  4. //      Test one Io Control Code   
  5. //   
  6. // TODO:   
  7. //      Pass appropriate arguments to your device and check   
  8. //      the return value   
  9. //   
  10. void Test_IOCTL_GET_KEY(void)   
  11. {   
  12. // Note that Input and Output are named from the point of view   
  13. // of the DEVICE:   
  14. //      bufInput  supplies data to the device   
  15. //      bufOutput is written by the device to return data to this application   
  16.   
  17.     CHAR    bufInput[IOCTL_INBUF_SIZE];     // Input to device   
  18.     CHAR    bufOutput[IOCTL_OUTBUF_SIZE];   // Output from device   
  19.     ULONG   nOutput;                        // Count written to bufOutput   
  20.   
  21.   
  22.     // Call device IO Control interface (IOCTL_GET_KEY) in driver   
  23.     printf("Issuing Ioctl to device - ");   
  24.     if (!DeviceIoControl(hDevice,   
  25.                          IOCTL_GET_KEY,   
  26.                          NULL,   
  27.                          0,   
  28.                          bufOutput,   
  29.                          IOCTL_OUTBUF_SIZE,   
  30.                          &nOutput,   
  31.                          NULL)   
  32.        )   
  33.     {   
  34.         printf("ERROR: DeviceIoControl returns %0x.\n", GetLastError());   
  35.         Exit(1);   
  36.     }   
  37.     else if(nOutput == 0)   
  38.     {   
  39.         printf("ERROR: DeviceIoControl complete, but Device not respond");   
  40.     }   
  41.     else  
  42.     {   
  43.         printf("Device responsed data:0x%.2x\n",bufOutput[0]);   
  44.   
  45.         if(bufOutput[0] & 0x01) //K1 Pressed   
  46.         {   
  47.             printf("K1 Pressed\n");   
  48.         }   
  49.         else  
  50.         {   
  51.             printf("K1 Unpressed\n");   
  52.         }   
  53.   
  54.         if(bufOutput[0] & 0x02) //K1 Pressed   
  55.         {   
  56.             printf("K2 Pressed\n");   
  57.         }   
  58.         else  
  59.         {   
  60.             printf("K2 Unpressed\n");   
  61.         }   
  62.     }   
  63. }   

  3)編譯驅動程序和測試程序,重新安裝驅動程序

下載編譯好的驅動

下載編譯好後的測試程序

下載驅動和測試程序源代碼(需要放到C:\Easy_USB_51_Programer目錄)

  4)在命令行窗口中运行测试程序,键入:TestApp i 0,代表发送请求代码为0x00的厂商请求,这个请求是控制LED的,运行结果如下:

  运行testapp i 0 后发现扩展板上的D0和D1被点亮了

 

(呵呵,我已經投PCB了,所以沒有用手工制作的那個原始東東來展示)

  这是用Bus Hound抓到的数据

  5)在命令行窗口中运行测试程序,键入:TestApp i 1,代表发送请求代码为0x01的厂商请求,这个请求是读取扩展板EXT-BOARD-A上按键状的,运行结果如下:

  下圖是用BusHound抓到的數據

 
 
 
本站程序由百合電子工作室開發和維護
Copyright @ baihe electric studio
渝ICP備09006681號-4