搜索
bottom↓
回复: 57

用STM32Cube简单实现自定义USB HID通信(实现步骤,无理论。)

  [复制链接]

出0入0汤圆

发表于 2015-8-20 12:10:44 | 显示全部楼层 |阅读模式
本帖最后由 icevel 于 2015-8-20 12:50 编辑

简单的用HID通信,本人不懂USB协议,只是想在一个项目中用HID代替串口,在网上找了一些例子,都需要搞懂USB协议,于是尝试用STM32Cube实现,适合拿过来就用。

0、开发环境:
        自己做的STM32F072RB的板子
        STM32CubeMX4.9.0+STM32CubeF0 Firmware Package V1.3.0
        IAR 7.2
1、建立、配置工程:
        打开STM32Cube,选择好器件
        打开USB Device(FS)
        选择要使用的其它功能,我打开了USART1用于输出数据
        在Middlewares里面选择Custom HID
       
       

        配置好时钟,我选择的时钟源是HSI48

        配置USB:        设备描述页默认即可,需要修改"Parameter Settings",将USBD_CUSTOM_HID_REPORT_DESC_SIZE 设置为33(此处33和程序中设备描述符对应)
                        USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 修改为64 ,输出节点的buffer大小,也就是每次发送数据的最大字节数。
       
2、生成代码
        用STM32Cube生成代码。       
3、修改代码实现发送
        修改usbd_custom_hid_if.c:
        在__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =    下面输入报告描述符:
        设置中的“USBD_CUSTOM_HID_REPORT_DESC_SIZE”  与此处对应。

  1. __ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
  2. {
  3.   /* USER CODE BEGIN 0 */
  4. //#ifdef 0
  5. 0x05, 0x8c, /* USAGE_PAGE (ST Page) */
  6. 0x09, 0x01, /* USAGE (Demo Kit) */
  7. 0xa1, 0x01, /* COLLECTION (Application) */
  8. /* 6 */

  9. // The Input report
  10. 0x09,0x03, // USAGE ID - Vendor defined
  11. 0x15,0x00, // LOGICAL_MINIMUM (0)
  12. 0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)
  13. 0x75,0x08, // REPORT_SIZE (8)
  14. 0x95,0x40, // REPORT_COUNT (40)
  15. 0x81,0x02, // INPUT (Data,Var,Abs)
  16. //19
  17. // The Output report
  18. 0x09,0x04, // USAGE ID - Vendor defined
  19. 0x15,0x00, // LOGICAL_MINIMUM (0)
  20. 0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)
  21. 0x75,0x08, // REPORT_SIZE (8)
  22. 0x95,0x40, // REPORT_COUNT (40)
  23. 0x91,0x02, // OUTPUT (Data,Var,Abs)
  24. //32
  25.   /* USER CODE END 0 */
  26. 0xC0    /*     END_COLLECTION                     */
  27.    
  28. };
复制代码


Stm32CUBE提供的API函数为“USBD_CUSTOM_HID_SendReport” ,直接调用即可:
  1. int main(void)
  2. {

  3.   /* USER CODE BEGIN 1 */
  4.   uint8_t HID_Buffer[]={"Hello,HID!~"};
  5.   /* USER CODE END 1 */

  6.   /* MCU Configuration----------------------------------------------------------*/

  7.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  8.   HAL_Init();

  9.   /* Configure the system clock */
  10.   SystemClock_Config();

  11.   /* Initialize all configured peripherals */
  12.   MX_GPIO_Init();
  13.   MX_USART1_UART_Init();
  14.   MX_USB_DEVICE_Init();

  15.   /* USER CODE BEGIN 2 */
  16.   printf("init_OK!\r\n");
  17.   /* USER CODE END 2 */

  18.   /* Infinite loop */
  19.   /* USER CODE BEGIN WHILE */
  20.   while (1)
  21.   {
  22.   /* USER CODE END WHILE */

  23.   /* USER CODE BEGIN 3 */
  24.   USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, HID_Buffer,65);
  25.   HAL_Delay(500);
  26.   }
  27.   /* USER CODE END 3 */

  28. }
复制代码


下载、调试:

已经有输出了。

4、修改代码实现接收:
        修改文件“usbd_custom_hid_if.c”,在函数“CUSTOM_HID_OutEvent_FS” 内加入数据处理代码即可:
  1. static int8_t CUSTOM_HID_OutEvent_FS  (uint8_t event_idx, uint8_t state)
  2. {
  3.   /* USER CODE BEGIN 6 */
  4.   USBD_CUSTOM_HID_HandleTypeDef     *hhid;
  5.   hhid = (USBD_CUSTOM_HID_HandleTypeDef*) hUsbDeviceFS.pClassData;
  6.   uint8_t rx_buf[65];
  7.   printf("%s",hhid->Report_buf);
  8.   switch(event_idx)
  9.   {
  10.   case 1: /* LED1 */
  11.     (state == 1) ? LED(1) : LED_off(1);
  12.     break;
  13.   case 2: /* LED2 */
  14.     (state == 1) ? LED(2) : LED_off(2);
  15.     break;
  16.   case 3: /* LED3 */
  17.     (state == 1) ? LED(3) : LED_off(3);
  18.     break;
  19.   case 4: /* LED4 */
  20.     (state == 1) ? LED(4) : LED_off(4);
  21.     break;
  22.    
  23.   default:
  24.     LED_all(0x00);
  25.     break;
  26.   }
复制代码


        下载、调试:
       
        可以用BusHound查看数据:
       


不是专职开发软件的,有时候玩玩,STM32Cube还是很方便的,只是有时候资料和文档不全,需要自己慢慢摸索。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2015-8-20 12:46:36 | 显示全部楼层
本帖最后由 icevel 于 2015-8-20 13:02 编辑

一些参考资料:

上位机打算用坛友的C#类实现:http://www.amobbs.com/thread-5492255-1-1.html

一些USB的资料:http://www.embed-net.com/thread-5-1-1.html
关于报告描述符:http://blog.csdn.net/cazicaquw/article/details/6724951
描述符生成工具:http://www.usb.org/developers/hidpage/



待解决的问题:
1、USBD_CUSTOM_HID_SendReport 只能发送64字节。
2、用USB调试助手调试的时候,第一个字节如果是0x00,会收不到。这个应该是调试助手的问题吧。

出0入0汤圆

发表于 2015-8-20 12:56:02 | 显示全部楼层
很不错的列子!

出0入0汤圆

发表于 2015-8-20 13:05:32 | 显示全部楼层
不错,话说HID最多也只能发送64字节数据,第一个字节是报告的ID,单片机端必须和PC端匹配,否则无法正常传输数据

出0入0汤圆

 楼主| 发表于 2015-8-20 13:14:48 | 显示全部楼层
wdluo 发表于 2015-8-20 13:05
不错,话说HID最多也只能发送64字节数据,第一个字节是报告的ID,单片机端必须和PC端匹配,否则无法正常传 ...

多谢。
        第一个问题是,只能是64,也就是说63就不行了。这个好像是ST的库的问题,封装的太深,我还没细看怎么解决。
        第二个问题,对这个调试助手不太了解,看起来它是把Report ID也当成内容来编辑了。 这个和我自己写的上位机通信是没有问题的。

出0入0汤圆

发表于 2015-8-20 13:24:27 | 显示全部楼层
不错,收藏了

出0入0汤圆

发表于 2015-8-20 13:29:27 | 显示全部楼层
我顶,楼主给力

出0入0汤圆

发表于 2015-8-26 14:15:25 | 显示全部楼层
mark 楼主做的相当好

出0入0汤圆

发表于 2015-9-2 18:56:11 | 显示全部楼层
例子详细!,mark.

出20入0汤圆

发表于 2015-9-3 13:06:34 | 显示全部楼层
  谢谢分享,以后用得到。

出0入0汤圆

发表于 2015-9-3 15:00:26 | 显示全部楼层
学习参考一下

出0入0汤圆

发表于 2015-9-6 15:39:46 | 显示全部楼层
stm32 HID,好东西,继续努力,学习中

出0入0汤圆

发表于 2015-9-22 14:56:14 | 显示全部楼层
电脑那边需要装驱动的么?还是直接写个程序就能找到HID设备!

出0入0汤圆

发表于 2015-9-22 15:33:47 | 显示全部楼层
好东西,当时研究HID好久

出0入0汤圆

发表于 2015-9-22 15:54:32 | 显示全部楼层
收藏了,我现在也正在做USB开发,不过我是按照协议来做的,如此简便的方法没试过,以后需要的时候再借鉴。

出0入0汤圆

 楼主| 发表于 2015-9-22 17:45:59 | 显示全部楼层
weidadejang 发表于 2015-9-22 14:56
电脑那边需要装驱动的么?还是直接写个程序就能找到HID设备!

HID免驱的。

出0入0汤圆

 楼主| 发表于 2015-9-22 17:47:28 | 显示全部楼层
myshworks 发表于 2015-9-22 15:54
收藏了,我现在也正在做USB开发,不过我是按照协议来做的,如此简便的方法没试过,以后需要的时候再借鉴。 ...

嗯,之前也用协议做出来过,后来换了平台,再弄一次会痛苦死。我不是专业写软件的,怎么简单实现功能怎么做了。
ST的库还是不错的

出100入101汤圆

发表于 2015-9-22 21:17:30 | 显示全部楼层
icevel 发表于 2015-8-20 13:14
多谢。
        第一个问题是,只能是64,也就是说63就不行了。这个好像是ST的库的问题,封装的太深,我还没细看 ...

应该是最大64字节

出0入0汤圆

发表于 2015-9-22 22:35:31 | 显示全部楼层
mark                        

出0入0汤圆

发表于 2015-9-23 00:11:19 来自手机 | 显示全部楼层
标记一下,后面试试。

出0入0汤圆

发表于 2016-4-25 17:03:49 | 显示全部楼层
楼主给力
一直在找这方面的资料
感谢

出0入0汤圆

发表于 2016-5-4 16:50:36 | 显示全部楼层
make   usb  hid

出0入0汤圆

发表于 2016-6-2 11:20:14 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2016-6-2 12:50:17 | 显示全部楼层
CUBE 还是挺方便的,可惜就是代码不怎么简洁,要优化要改的 地方太多了。

出0入0汤圆

发表于 2016-6-2 12:58:17 | 显示全部楼层
用过,感觉生成的代码太多,看起来很费力,最后放弃了,回到库函数上了。

出0入0汤圆

发表于 2016-11-11 20:31:12 | 显示全部楼层
很不错的列子!

出0入0汤圆

发表于 2016-11-22 08:07:07 | 显示全部楼层

出0入0汤圆

发表于 2016-11-22 08:57:41 | 显示全部楼层
学习了,感谢分享。

出0入0汤圆

发表于 2016-11-25 19:59:13 来自手机 | 显示全部楼层
STM32 USB-HID 赞

出0入0汤圆

发表于 2016-12-14 09:59:11 | 显示全部楼层
很不错,学习了

出0入0汤圆

发表于 2016-12-14 11:08:07 | 显示全部楼层
make   usb  hid

出0入0汤圆

发表于 2016-12-14 13:03:01 | 显示全部楼层
很不错,学习了

出0入0汤圆

发表于 2016-12-25 22:44:33 | 显示全部楼层
学习了收藏了!!!

出0入0汤圆

发表于 2016-12-26 10:51:24 | 显示全部楼层
不错,很详细

出0入0汤圆

发表于 2017-2-10 10:09:31 | 显示全部楼层
这个我发现USB读写速度有点慢,不知道是什么原因。也就是电脑的usb发数据给mcu后,mcu感觉要等好一会儿

出0入10汤圆

发表于 2017-2-22 14:07:38 | 显示全部楼层
dswkl11 发表于 2017-2-10 10:09
这个我发现USB读写速度有点慢,不知道是什么原因。也就是电脑的usb发数据给mcu后,mcu感觉要等好一会儿 ...

HID有个时间间隔的定义,你把那个时间改小就是了,应该就在报告描述符里面

出0入0汤圆

发表于 2017-2-22 14:59:25 | 显示全部楼层
dwiller_ARM 发表于 2017-2-22 14:07
HID有个时间间隔的定义,你把那个时间改小就是了,应该就在报告描述符里面 ...

改了一下,确实是快了点,谢谢啊!好像你对USB HID好熟悉啊

出0入0汤圆

发表于 2017-2-22 16:09:51 | 显示全部楼层
为什么我电脑上每次发送几个字节  BUS hound  的OUT 都显示64个呢?

出0入10汤圆

发表于 2017-2-22 16:12:25 | 显示全部楼层
dswkl11 发表于 2017-2-22 14:59
改了一下,确实是快了点,谢谢啊!好像你对USB HID好熟悉啊

我也是最近刚好看到USB-HID,自己学着玩,想写个上位机,测试下USB的速度

出0入10汤圆

发表于 2017-2-22 16:14:10 | 显示全部楼层
Xy201207 发表于 2017-2-22 16:09
为什么我电脑上每次发送几个字节  BUS hound  的OUT 都显示64个呢?

看你报告描述符的OUT报告描述符定义多长啊!一般定义64字节,就只能发64字节了,多了或者少了反而不成功的

出0入0汤圆

发表于 2017-2-22 16:15:03 | 显示全部楼层
wzyllgx 发表于 2016-6-2 12:50
CUBE 还是挺方便的,可惜就是代码不怎么简洁,要优化要改的 地方太多了。

那个结构化好
在文档好的情况下 好接手

出0入0汤圆

发表于 2017-3-4 00:38:42 来自手机 | 显示全部楼层
以前做lpc的可以不定长发送,stm32可能封装的太深了

出0入0汤圆

发表于 2017-3-4 00:40:39 来自手机 | 显示全部楼层
网上查了一下,好像发送少于枚举阶段的长度,需要发一个终止符,具体什么我还在研究

出0入0汤圆

发表于 2018-1-17 15:38:02 | 显示全部楼层
请教一下,下面的这几个函数对应于 STM32Cube生成的是那些函数呀?
extern void  usbd_hid_init              (void);
extern BOOL  usbd_hid_get_report_trigger(U8 rid,   U8 *buf, int len);
extern int   usbd_hid_get_report        (U8 rtype, U8 rid, U8 *buf, U8  req);
extern void  usbd_hid_set_report        (U8 rtype, U8 rid, U8 *buf, int len, U8 req);

出0入0汤圆

发表于 2018-1-17 15:54:14 | 显示全部楼层
STM32 USB前几年也做过一个,需要的话也发上来

出0入0汤圆

发表于 2018-1-17 16:13:47 | 显示全部楼层
wazhiyi 发表于 2018-1-17 15:54
STM32 USB前几年也做过一个,需要的话也发上来

正在尝试 CMSIS_DAP_STM32 这个程序里面的USB驱动改成 HAL的库来运行.结果所用到的函数对不上.对USB不了解.

出0入0汤圆

发表于 2018-1-18 20:24:50 来自手机 | 显示全部楼层
谢谢分享啦,先收藏起来了!

出0入0汤圆

发表于 2018-1-25 00:45:01 | 显示全部楼层
看了几天的USB资料,结果真正只需修改几行代码.....累啊......

出0入0汤圆

发表于 2018-1-29 10:34:47 | 显示全部楼层
现在还没有明白怎么用的,设置usbhid的收发时间是1ms,结构设备给PC端的数据响应是30ms,有知道为什么的吗?还是使用hal库的效率问题

出0入0汤圆

发表于 2018-1-29 13:36:49 | 显示全部楼层
蚁族 发表于 2018-1-29 10:34
现在还没有明白怎么用的,设置usbhid的收发时间是1ms,结构设备给PC端的数据响应是30ms,有知道为什么的吗 ...

你处理数据了吧,纯收发1ms是可以的。

出0入0汤圆

发表于 2018-3-8 18:48:37 | 显示全部楼层
mll2015 发表于 2018-1-29 13:36
你处理数据了吧,纯收发1ms是可以的。

请教一下,HID设备是如何设置为哪种类型的,就是说如何在STM32代码里面配置,可让电脑识别为 鼠标、键盘、或自定义的HID设备?
是不是只要定义某个ID变量?还是说要做很多配置?网上都没有详细说这个问题

出0入0汤圆

发表于 2018-3-9 09:14:41 | 显示全部楼层
mcu005 发表于 2018-3-8 18:48
请教一下,HID设备是如何设置为哪种类型的,就是说如何在STM32代码里面配置,可让电脑识别为 鼠标、键盘 ...

修改STM32代码里面的配置描述符就可以了。
代码如下:
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 */

出0入0汤圆

发表于 2018-3-9 19:11:47 | 显示全部楼层
mll2015 发表于 2018-3-9 09:14
修改STM32代码里面的配置描述符就可以了。
代码如下:
USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorTyp ...

好的,非常感谢

出0入0汤圆

发表于 2018-3-29 09:32:06 | 显示全部楼层
mark  usb-custom-hid

出0入0汤圆

发表于 2018-3-30 23:37:27 | 显示全部楼层
很不错,学习了

出0入0汤圆

发表于 2018-8-23 11:59:27 | 显示全部楼层
dwiller_ARM 发表于 2017-2-22 14:07
HID有个时间间隔的定义,你把那个时间改小就是了,应该就在报告描述符里面 ...

太久没搞,现在又忘记了,还好后面找出来了,在 usbd_customhid.c 里面设置:

/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
...
0x20,          /*bInterval: Polling Interval (20 ms)*/
...
0x20,          /*bInterval: Polling Interval (20 ms)*/
....
}

这里设置,希望哪天又忘记后再看这个回复...

出0入0汤圆

发表于 2019-2-21 22:44:29 | 显示全部楼层
很不错,学习了

出0入8汤圆

发表于 2019-5-20 10:14:48 | 显示全部楼层
dswkl11 发表于 2018-8-23 11:59
太久没搞,现在又忘记了,还好后面找出来了,在 usbd_customhid.c 里面设置:

/* USB CUSTOM_HID device ...

多谢  , 我也搞忘记了  ,  一改 usb速度上来了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-18 13:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表