STM32F103系列USB的学习过程及使用心得(二)(USB HID协议篇)

13 篇文章 1 订阅
3 篇文章 0 订阅

在熟悉USB的协议后,感觉能自己做出些东西的就是HID协议了,因为HID的设备对于上位机开发容易很多,不用涉及各个操作系统和USB主设备的等等知识。按照HID协议写好的下位机程序,在stm32的芯片上跑起来,电脑就会识别出来的。

而且ST官方有个测试HID设备的Windows小软件,也很方便,省的自己开发上位机了

1、对HID设备的理解

(1)对于stm32的HID设备编程,最核心的就是对报告描述符的定义,具体内容在USB官网的HID版面里可以下载协议书和Usage Table来自定义HID设备;

(2)USB的官网有给一个名为HID descriptor tool的报告描述符生成工具,对于报告描述符的查错很有用,想自己写一份完整的HID报告描述符还得靠协议文档。但是可以先采用一些网上和stm32官例的代码先跑跑程序,看看效果,增加一下自己学习的动力。

2、使用HID协议的报告描述符

(1)在程序中我没使用报告ID,所以默认向0号ID发送包,(这里补充一下,我的自定义全速USB设备一个USB数据包为64字节,但是发送传输过程中,stm32会在之前加个报告ID,为一个字节的宽度),所以,上位机发送和接收信息只能在0号ID,其实这个ID很有用,主要是区分不同数据的,因为HID控制一般传输的都是少量字节数据,很少发整一包64字节,对于数据的分类很有帮助,而且很多HID设备都是二进制形式的状态数据,是按bit为单位进行控制通信的,用不着要收发字符串。

(2)为了通信测试,我直接按字节传输,就是上下位机收发字符串,没有对HID报告描述符的input、output和feature做太多定义

eg:

0x05, 0x8c, /* USAGE_PAGE (ST Page) */ 
0x09, 0x01, /* USAGE (Demo Kit) */ 
0xa1, 0x01, /* COLLECTION (Application) */ 

// The Input report 
0x09,0x0
1, // USAGE ID - Vendor defined 
0x15,0x00, // LOGICAL_MINIMUM (0) 
0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255) 
0x75,0x08, // REPORT_SIZE (8bit) 
0x95,0x40, // REPORT_COUNT (64Byte) 
0x81,0x02, // INPUT (Data,Var,Abs) 

// The Output report 
0x09,0x0
2, // USAGE ID - Vendor defined 
0x15,0x00, // LOGICAL_MINIMUM (0) 
0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255) 
0x75,0x08, // REPORT_SIZE (8bit) 
0x95,0x40, // REPORT_COUNT (64Byte) 
0x91,0x02, // OUTPUT (Data,Var,Abs) 
0x09,0x04, // USAGE ID - Vendor defined 
0xb1,0x82,
 //FEATURE (Data,Var,Abs,Vol)

0xc0 /* END_COLLECTION */ 


**********之后,运行程序时,切记向0号ID传输数据,否则,发不出去也收不到……Orz

3、报告描述符书写规则

这个要啃USB官方的HID协议和Usage Tables那俩文件了,书写完毕后用官网给的HID descriptor tool检查一下,这里我还没有弄明白feature和report的用法,不过最好都写上,要不然可能有问题,因为我是之前没有feature,只有report,计算机是识别了,但是测试HID设备的软件识别不出output report……(/ □ \),然后加上feature就识别了,没明白是怎么一回事啊o_O


  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用STM32F103USB HID代码的基本步骤: 1. 配置系统时钟和GPIO引脚:将所有需要使用的GPIO引脚配置为适当的模式和速率。同时,请确保系统时钟的频率满足USB时钟要求。 2. 初始化USB控制器:使用HAL库初始化USB控制器,这包括设置USB时钟、配置USB控制器并启用USB断。 3. 配置USB HID库:使用USB HID库配置USB设备的ID、报告描述符和端点。 4. 实现USB HID回调函数:实现USB HID回调函数以处理来自主机的USB HID传输。这些回调函数包括数据接收、数据发送和USB重置等。 5. 处理USB HID数据:在USB HID回调函数,处理来自主机的数据,并将响应数据发送回主机。 下面是一个使用STM32F103USB HID的简单代码示例,仅供参考: ```c #include "stm32f1xx_hal.h" #include "usbd_core.h" #include "usbd_desc.h" #include "usbd_hid.h" extern USBD_HandleTypeDef hUsbDeviceFS; int main(void) { // 配置系统时钟和GPIO引脚 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); // 初始化USB控制器 MX_USB_DEVICE_Init(); // 配置USB HIDUSBD_HID_Init(&hUsbDeviceFS, HID_REPORT_DESC_SIZE, HID_Desc); // 等待USB断 while (1) { // 处理USB HID数据 USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)hUsbDeviceFS.pClassData; if (hhid->state == HID_IDLE) { // 等待数据发送 } } } // 实现USB HID回调函数 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { USBD_HID_Setup(&hUsbDeviceFS, (uint8_t *)hpcd->Setup); } void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)hUsbDeviceFS.pClassData; if (hhid->state == HID_IDLE) { // 处理数据 USBD_HID_ReceivePacket(&hUsbDeviceFS); } } void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)hUsbDeviceFS.pClassData; if (hhid->state == HID_IDLE) { // 数据已发送 } } void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) { // 处理SOF事件 } } void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)hUsbDeviceFS.pClassData; hhid->state = HID_IDLE; USBD_HID_Reset(&hUsbDeviceFS); } ``` 需要注意的是,以上代码仅提供了基本框架和USB HID回调函数的实现,具体的报告描述符和数据处理需要根据您的具体应用进行实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值