前言
由于项目需要,要实现USB组合设备(Custom HID + MSC)功能。
我的思路是先使用STM32CubeMX工具生成 Custom HID工程,再生成一个MSC的工程,两个功能独立调试OK之后,进行组合调试。本文为后续组合设备功能做铺垫。
实验步骤
1、打开STM32CubeMX工具,选择你的MCU型号
笔者这里使用的是STM32H7的MCU,你们选择自己的MCU型号即可(比如,F103C8T6,F407ZGT6等)
2、配置系统参数,USB参数等
笔者的这颗MCU使用的是外部8M的晶振,主频倍频到了 550M,其他MCU根据实际情况配置主频即可,但是USB的时钟一定要设置为48M
调试模式选择SW 两线模式
堆栈空间尽量设置大一点
最后生成我们的工程即可。
3、修改工程代码并编译
初次编译我们的工程OK之后,开始我们的修改。
由于我的MCU的原因,作为设备时只支持高速模式(HS)而不是全速模式(FS)两者只是通讯速度上有差异,修改时不用特别在意。
首先,修改usbd_custom_hid_if.c文件中HID自定义报告描述符的数组内容如下
/** Usb custom HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_HS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
/* USER CODE BEGIN 1 */
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1) 表示一个报文标签之类的用途类页
0x09, 0x01, // USAGE (Vendor Usage 1) 表示一个报告ID标志
0xa1, 0x01, // COLLECTION (Application) 表示应用集合,要以下面最后的0xc0结束它
0x09, 0x01, // USAGE (Vendor Usage 1)功能的一个卷标志
0x15, 0x00, // LOGICAL_MINIMUM (0) 表示每个传输数据限定为0
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 表示每个传输数据的最大值限定为255
0x95, 0x40, // REPORT_COUNT (64) 每次发送的数据长度,这里是64位
0x75, 0x08, // REPORT_SIZE (8) 同下REPORT_SIZE
0x81, 0x02, // INPUT (Data,Var,Abs) 表示USB要输入数据到PC的功能
0x09, 0x01, // USAGE (Vendor Usage 1) 每个功能的一个卷标志
0x15, 0x00, // LOGICAL_MINIMUM (0) 表示每个传输数据限定为0
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 表示每个传输数据的最大值限定为255
0x95, 0x40, // REPORT_COUNT (64) 每次接收的数据长度,这里是64位
0x75, 0x08, // REPORT_SIZE (8) 传输字段的宽度为8bit,表示每个传输的数据范围为0~ffff ffff
0x91, 0x02, // OUTPUT (Data,Var,Abs) 表示USB设备要接收PC的数据的功能
// 0xc0 // END_COLLECTION 结束标志
/* USER CODE END 1 */
0xC0 /* END_COLLECTION */
};
为何要这样配置,是参考的一篇文章,我把链接贴出来,大家自行去查看
链接: https://www.cnblogs.com/xingboy/p/9913963.html
然后取消发送函数的注释,并添加到usbd_custom_hid_if.h中
int8_t USBD_CUSTOM_HID_SendReport_HS(uint8_t *report, uint16_t len)
{
return USBD_CUSTOM_HID_SendReport(&hUsbDeviceHS, report, len);
}
我的测试方法,PC给该设备发送数据,设备收到之后将信息返回给PC
修改接收函数
uint8_t receive_Flag = 0; //接收到数据标志位
uint8_t receive_buffer[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];//缓存区,一次缓存一帧,即最大64个字节
static int8_t CUSTOM_HID_OutEvent_HS(uint8_t event_idx, uint8_t state)
{
/* USER CODE BEGIN 10 */
UNUSED(event_idx);
UNUSED(state);
/* Start next USB packet transfer once data processing is completed */
if (USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceHS) != (uint8_t)USBD_OK)
{
return -1;
}
receive_Flag = 1; //接收数据标志位 表示接收到一帧数据
memcpy(&receive_buffer[0], hUsbDeviceHS.pClassData, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); //将接收到的数据存入自己定义的缓冲数组中
return (USBD_OK);
/* USER CODE END 10 */
}
注意:USB数据传输是多帧传输,一帧数据最大为64个字节
main函数如下
#include "usbd_custom_hid_if.h"
int main(void)
{
MPU_Config();
HAL_Init();
SystemClock_Config();
PeriphCommonClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
while (1)
{
extern uint8_t receive_Flag;
extern uint8_t receive_buffer[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
if (receive_Flag) {
receive_Flag = 0;
USBD_CUSTOM_HID_SendReport_HS(receive_buffer, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
}
}
}
下载验证