原创 STM32 USB HID开发实例,实现USB双向通信

2010-6-22 13:29 17787 9 47 分类: MCU/ 嵌入式

STM32 USB HID开发实例,实现USB双向通信。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


STM32 ARM平台上实现USBPC端得通信(ICSTM32F10XX系列)。本文提供一个例程(已测试通过),不用了解任何USB协议(当然了解USB相关协议或描述表的意义是很必要的),在此例程上,稍作修改,即可开展你的项目或学习或进行产品开发。


ST中我们可以获得了USB相关的一个HID例程,但是官方例子中只是用到2个端点。数据只收不发。


本例程中,用到了3USB端点,实现PC上位机与下位机见双向通信。EP0为控制端点(必须的,这是因为系统默认端点0作为控制传输端点),EP1INTERRUPT OUT端点(数据输出端,即PCMCU发送数据段),EP2INTERRUPT OUT端点(数据输入端,即MCUPC发送数据)。


实现过程,我们需要修改一下HID的描述表,修改如下(有详细注释)


/* USB Configuration Descriptor */


/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */


const u8 CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =


  {


    0x09, /* bLength: Configuation Descriptor size */


    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */


    CUSTOMHID_SIZ_CONFIG_DESC,


    /* wTotalLength: Bytes returned */


    0x00,


    0x01,         /* bNumInterfaces: 1 interface */


    0x01,         /* bConfigurationValue: Configuration value */


    0x00,         /* iConfiguration: Index of string descriptor describing


                                 the configuration*/


    0xC0,         /* bmAttributes: Bus powered */


                  /*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits */


    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */


//    0x96,         /* MaxPower 300 mA: this current is used for detecting Vbus */


    /************** Descriptor of Custom HID interface ****************/


    /* 09 */


    0x09,         /* bLength: Interface Descriptor size */


    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */


    0x00,         /* bInterfaceNumber: Number of Interface */


    0x00,         /* bAlternateSetting: Alternate setting */


    0x02,         /* bNumEndpoints */


    0x03,         /* bInterfaceClass: HID */


    0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */


    0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */


    0,            /* iInterface: Index of string descriptor */


    /******************** Descriptor of Custom HID HID ********************/


    /* 18 */


    0x09,         /* bLength: HID Descriptor size */


    HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */


    0x10,         /* bcdHID: HID Class Spec release number */


    0x01,


    0x00,         /* bCountryCode: Hardware target country */


    0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */


    0x22,         /* bDescriptorType */


    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */


    0x00,


    /******************** Descriptor of Custom HID endpoints ******************/


    /* 27 */


    0x07,          /* bLength: Endpoint Descriptor size */


    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */


 


    0x82,          /* bEndpointAddress: Endpoint Address (IN) */              


                   // bit 3...0 : the endpoint number


                   // bit 6...4 : reserved


                    // bit 7     : 0(OUT), 1(IN)


    0x03,          /* bmAttributes: Interrupt endpoint */


    0x40,//0x02,          /* wMaxPacketSize: 20 Bytes max */


    0x00,


    0x20,          /* bInterval: Polling Interval (32 ms) */


    /* 34 */


      


    0x07,  /* bLength: Endpoint Descriptor size */


    USB_ENDPOINT_DESCRIPTOR_TYPE,  /* bDescriptorType: */


           /*  Endpoint descriptor type */


    0x01,  /* bEndpointAddress: */


           /*  Endpoint Address (OUT) */


    0x03,  /* bmAttributes: Interrupt endpoint */


    0x40,//0x02,  /* wMaxPacketSize: 20 Bytes max  */


    0x00,


    0x10,  /* bInterval: Polling Interval (16 ms) */


    /* 41 */


  }; /* CustomHID_ConfigDescriptor */


关于如何理解HID 描述表,请参考USB HID协议1.1版本,相关资料可以在网络上搜索得到。


在此,现提供KEIL MDK IAR EWARM 5.4版本的例子,欢迎下载。萝卜青菜,喜欢用MDK,就MDK,喜欢EWARM,就EWARM。同样这里有见有意思的事,在全编译的情况下,EWARM要比MDK编译速度要快一些。


相关测试结果如下:


通过呀呀USB_hid Bus Hound相关工具,先发一包数据给下位机,这样下位机每隔1s会发送一包数据。结果如图:


USB_hid可以在本博客上下载^_^: http://blog.ednchina.com/itspy


点击看大图


 


源码下载:


KEIL MDK 版本(4.0):


https://static.assets-stash.eet-china.com/album/old-resources/2010/6/22/97c50783-e683-4e89-9e7d-d9e41a7e9cd2.rar


 


IAR EWARM 版本(v5.4):


https://static.assets-stash.eet-china.com/album/old-resources/2010/6/22/97c50783-e683-4e89-9e7d-d9e41a7e9cd2.rar" target=_blank> 


文章评论38条评论)

登录后参与讨论

用户377235 2016-3-2 21:05

为什么 只能发比22个字节少的数呢

用户967597 2015-6-12 11:44

博主你好! 首先非常感谢你,你的文章及例程给了我很大的帮助。经过两天的折腾libusb 终天可以查到stm32-hid 了。原因是没有安装驱动。一直没有往这方面想是没装libusb驱动前用博主的“呀呀USB_hid”可以连接并通信。所以,我想知道博主是通过什么方法实现的,给我说说大至方向就行,其它的我想办法完成。希望你能百忙中给点提示,谢谢! E-Addr:ly_harryluo@163.com

用户403160 2013-10-20 22:00

由衷地谢谢您的分享

用户377235 2013-3-14 20:27

首先感谢您给我们这些初学者提供这么好的资源。在学习的过程中,我尝试在板子上跑您的程序,但是我一直没弄明白USB_Receive*** 这个变量是怎么控制的?他是软件控制,还是当USB接收到上位机的数据后硬件控制的??比如这段程序 USB_Interrupts_Config(); Set_USBClock(); USB_Init(); USB_ReceiveF.lg = FALSE; while(1) // { if (TimeCount && USB_ReceiveF-lg == TRUE) //收到后上位机的数据后,将1S发送一次数据给PC { USB_SendString("Hi,PC! I'm STM32-ARM"); TimeCount = 0x00; } } USB_Receive***怎么变成的TRUE呢??

用户421709 2012-8-10 14:46

硬件上怎么连接的啊??

用户377235 2012-6-9 18:08

学习中 非常感谢版主!

用户1313238 2012-4-25 11:26

EP1为INTERRUPT OUT端点(数据输出端,即PC向MCU发送数据段) 接收的数据与PC发的数据不对?

用户377235 2012-4-12 13:57

问一下,这个双向通信的例程要不要自己制作驱动程序,我用usb调试助手能识别这个设备部

用户191241 2012-3-30 17:27

版主我想问下stm32f103的HID设备与电脑双向通信报告最长多长?怎么改输入输出报告的长度,谢谢博主!

hjf2002_hk_735514074 2012-2-29 09:43

多谢分享经验!
相关推荐阅读
用户1369714 2012-04-12 12:34
大家好,我是itspy,关于这个博客,请大家看过来!
大家好,我是itspy,关于这个博客...,很失望,以后不会用了 如果大家有什么问题,请到我的另一个博客去留言吧 我也很希望跟大家做交流,有什么技术问题,itspy会很乐意帮助的,新博客欢...
用户1369714 2011-08-07 14:35
uip 移植在rt-thread上的源码
*/本人在以前开发过程中移植uIP到RT-Thread实时线程系统,有需要用到项目中的朋友可以参考一下。 附件是源码包,在以太网驱动采用DM9000,驱动程序和移植文件uipif.c在源码包下(rt...
用户1369714 2011-01-13 10:32
Linux内核的社会视角--Mr. Process的一生
         Linux内核是一个无比复杂的系统,要想看清大致的脉络也非易事。其实,可以把运行中的Linux想像成一个人类的社会,当中的进程就是社会中的人。人有生老病死,进程有创建、异常、终止。人...
用户1369714 2011-01-08 12:39
RT-Thread Radio 网络播放器--初次零距离接触!
      今天很高兴, 收到了RT-Thread Radio套件,还有ffx和RT-Thread工作室写的新书《RT-Thread 实时操作系统 编程指南》。 如此令人快乐的事,如此高兴,实在是想不...
用户1369714 2011-01-05 15:43
如何编写linux的驱动程序
如何编写Linux的驱动程序编写linux驱动程序,应该是一件得心应手的事,因为linux是开源的,从上往下或从下往上,一切都是那么的光明磊落的呈现于眼前。只要你愿意,你可随意了解你所想知道的东西。L...
用户1369714 2010-12-28 10:12
Busybox制作Linux根文件系统
Busybox ——嵌入式Linux中的瑞士军刀利用busybox-1.13.0制作linux根文件系统(yaffs2)源码下载:http://www.busybox.net/downloads/操作...
我要评论
38
9
关闭 站长推荐上一条 /2 下一条