前期准备:

一、硬件资源:STM32F103,USB-FS固件库。

链接:

STM32 之 标准外设版USB驱动库详解(架构+文件+函数+使用说明+示例程序)

https://blog.csdn.net/ZCShouCSDN/article/details/78936456?utm_source=blogxgwz1

二、调试软件:usbtrace3.0或者BusHound,用于看USB设备的信息。KEIL编译环境-用于开发。

后续相关工作:

(1)用STM32CubeMX配置,具体实现其它的HID,自定义虚拟串口等实验;

链接:利用STM32CubeMX生成BID通信

https://www.cnblogs.com/libra13179/p/6891685.html?utm_source=itdadao&utm_medium=referral

(2)了解USB的枚举配置过程。

链接:https://blog.csdn.net/huohongpeng/article/details/54927337

三、重点掌握的知识点:

(1)USB设备描述符,

(2)STM32F103的USB-FS固件库相关架构;

(3)USB的数据发送与接收,即通信原理;

本次USB做成复合设备,HID+AUDIO_MIDI设备,HID与上位机通信,MIDI设备与主流音乐DAW软件通信

(4)调试USB数据包的过程;

(5)移植步骤:

--配置好相关的KEIL工程,或者STM32CubeMX配置;

--添加USB固件库里面的HID工程-参考正点原子的STM32F1开发指南-库函数版本_V3.1;

--修改相应的usb描述符,VID/PID等,可以添加原子自己的USB启动通用函数;

(6)技术参考以下博文:

1-STM32 USB 之从0开始移植笔记https://blog.csdn.net/gzzxbcxm2005/article/details/51347624

2-从头调试STM32 HIDhttp://www.cnblogs.com/sz189981/p/7291121.html

3-移植STM32固件库用于HID双向通信https://blog.csdn.net/a827415225/article/details/51745013

调试中期:

一、移植好修改配置描述符后插入PC端,显示HID-人体学输入设备与USB输入设备,AUDIO设备也增加了一个

图一:

​图二:

BUS Hound 软件捕捉到的信息:

至此,产品已经能正确的MIDI通信,至于HID上位机通信,后面将补充代码

二、程序解析

(1)USB数据包的发送与接收;

--USB数据的发送与接收流程分析https://www.cnblogs.com/skl374199080/p/3910066.html

自己重写的MIDI发送代码:

uint32_t USB_SendData(uint8_t *data,uint32_t dataNum)
{
// #ifndef STM32F10X_MD //¸Ä±äÈ«¾Ö¶¨Òå
//½«Êý¾Ýͨ¹ýUSB·¢ËͳöÈ¥-----------by EP2¶Ëµã·¢ËÍTX
UserToPMABufferCopy(data, ENDP4_TXADDR, dataNum);
SetEPTxCount(ENDP4, );
SetEPTxValid(ENDP4); //ʹÄÜ
// #else
// USB_SIL_Write(EP4_IN, data, dataNum);
// SetEPTxValid(ENDP4);
// #endif
//return dataNum;
}
uint32_t USB_GetData(uint8_t *data,uint32_t dataNum)
{
uint32_t len=;
if(dataNum>sizeof(USB_Receive_Buffer))
{
dataNum = sizeof(USB_Receive_Buffer);
}
for(len=;len<dataNum;len++)
{
*data=USB_Receive_Buffer[len];
data++;
}
return dataNum; //·µ»Ø
}

(2)主要的USB描述符--HID+AUDIO_MIDI设备

/* USB Standard Device Descriptor */
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
{
0x12, /*bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
0x10, /*bcdUSB 1.0*/
0x01,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
0x40, /*bMaxPacketSize 64 bytes*/ //ÕâÀïµÄsize»áÔì³ÉÉ豸ÇëÇóÃèÊö·ûʧ°Ü
/************** ÉèÖÃVID and PID ****************/
0x11, /*idVendor (0x0483)*/
0x20,
0x15, /*idProduct = 0x5750*/
0x07, 0x00, /*bcdDevice rel. 2.00*/
0x00,
, /*Index of string descriptor describing
manufacturer */
, /*Index of string descriptor describing
product*/
, /*Index of string descriptor describing the
device serial number */
0x01 /*bNumConfigurations*/
};
/* CustomHID_DeviceDescriptor */ /* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
/************** Descriptor of standard audio +HID Configuration ****************///ÅäÖÃÃèÊö·û
0x09, /* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
0x85, //Õâ¸ö³¤¶ÈÐèҪȷ¶¨ÏÂ133
/* wTotalLength: Bytes returned */
0x00,
0x03, /* bNumInterfaces: 1 HID interface +MIDI 2 interface 03*/
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describingthe configuration*/
0x00, /* bmAttributes: Self powered */
0xFA, /* MaxPower 0xFA:500 mA */ /************** Descriptor of µÚÒ»¸ö HID ½Ó¿ÚÃèÊö·û ****************/ /* Interface Descriptor 0/0 HID, 2 Endpoints */
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */ //¸Ã½Ó¿ÚµÄ±àºÅ0
0x00, /* bAlternateSetting: Alternate setting */ //±¸ÓñàºÅ
0x02, /* bNumEndpoints */ //¶ËµãÊýÁ¿2£¬ÖжÏÊäÈëºÍÊä³ö
0x03, /* bInterfaceClass: HID */
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ //ʹÓõÄЭÒé
0x00, /* iInterface: Index of string descriptor */ //¸Ã½Ó¿ÚµÄ×Ö·û´®Ë÷ÒýºÅ0ûÓÐ×Ö·û´® /******************** Descriptor of HID ÃèÊö·û ********************/
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID *///0x21
0x11, /* bcdHID: HID Class Spec release number *///HID 1.1ЭÒé
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow *///ϼ¶ÃèÊö·ûÊýÁ¿-±¨¸æÃèÊö·û
0x22, /* bDescriptorType */ //ϼ¶ÃèÊö·ûÀàÐÍΪ±¨¸æÃèÊö·û£¬±àºÅ0x22
/* wItemLength: Total length of Report descriptor */
CUSTOMHID_SIZ_REPORT_DESC, //±¨¸æÃèÊö·ûµÄ´óС
0x00, /******************** Descriptor of Custom HID endpoints ¶ËµãÃèÊö·û******************/
/* Endpoint Descriptor 81 1 In, Interrupt, 1 ms */ //ÊäÈë¶Ëµã
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
0x81, /* bEndpointAddress: Endpoint Address (IN) */ // 1 IN Endpoint
0x03, /* bmAttributes: Interrupt endpoint */ //Ñ¡ÔñΪÖж϶˵ã
0x20, /* wMaxPacketSize: 32 Bytes max */ //µÍ×Ö½ÚÔÚÇ°
0x00,
0x01, /* bInterval: Polling Interval (1 ms) */ //¶Ëµã²éѯʱ¼ä /* Endpoint Descriptor 02 2 Out, Interrupt, 1 ms*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
0x02, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
0x20, /* wMaxPacketSize: 32 Bytes max */ //µÍ×Ö½ÚÔÚÇ°
0x00,
0x01, /* bInterval: Polling Interval (1 ms) */ //¶Ëµã²éѯʱ¼ä /************** Descriptor of µÚ¶þ¸ö MIDI AUDIO ½Ó¿ÚÃèÊö·û ****************/
/* Interface Descriptor 1/0 Audio, 0 Endpoints */ //ûÓж˵ã
0x09, /*bLength: Interface Descriptor size*/
0x04, /*bDescriptorType: Interface descriptor type*/
0x01, /*bInterfaceNumber: Number of Interface*/ //½Ó¿Ú±àºÅ01
0x00, /*bAlternateSetting: Alternate setting*/
0x00, /*bNumEndpoints: no endpoints*/
0x01, /*bInterfaceClass: Audio device class 0x01*/
0x01, /*bInterfaceSubClass : Audio control*/
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0x00, /*iInterface: Index of string descriptor*/ /* Audio Control Interface Header Descriptor */
//class_specific_interface_descritor //ÀàÌØÊâ½Ó¿ÚÃèÊö·û£ºÀàÌØÊâÒôƵ¿ØÖƽӿÚ
0x09, //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x24, //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ
0x01, //ÃèÊö·û×ÓÀà
0x00,
0x01, //×ÓÀà°æ±¾£¬1.0
0x09,
0x00, //ÀàÌØÊâÃèÊö´óС
0x01, //Á÷½Ó¿ÚÊýÁ¿
0x02, //MIDI Á÷½Ó¿Ú1ÊôÓÚ´ËÒôƵ¿ØÖÆ½Ó¿Ú /* Interface Descriptor 2/0 Audio, 2 Endpoints */ //Á½¸ö¶Ëµã
//Standard MS Interface Descriptor£¬Ê¹ÓÃÁ½¸öÅúÁ¿¶ËµãÀ´·Ö±ðÊä³öºÍÊäÈëMIDIÊý¾ÝÁ÷---µÚ¶þ¸ö½Ó¿Ú
0x09, //bLength½Ó¿ÚÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x04, //bDescriptorType½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ
0x02, //bInterfaceNumber½Ó¿Ú±àºÅΪ02
0x00, //bAlternateSetting±¸ÓñàºÅΪ0
0x02, //bNumEndpoints·Ç0¶ËµãÊýÁ¿Îª2 bNumEndpoints,Ò»¶ÔÅúÁ¿¶Ëµã
0x01, //bInterfaceClassÒôƵÉ豸£¨AUDIO£©Àà0x01 bInterfaceSubClass0x03
0x03, //ʹÓõÄ×ÓÀࣺMIDIÁ÷(MIDI STREAMING)Àà
0x00, //δÓÃbInterfaceProtocol
0x00, //δÓÃbInterfaceProtocol /************** ÀàÌØÊâMIDIÁ÷½Ó¿ÚÃèÊö·û----ÖصãÅäÖÃ**************************************/
/*ÀàÌØÊâMIDIÁ÷ÃèÊöÉ豸ÄÚ¸÷¸öÄ£¿éµÄÁ¬½Ó¹Øϵ£¬ÓÐËÄÖÖ²å¿×£ºÄÚǶÊäÈ룬ÄÚǶÊä³ö£¬ÍⲿÊäÈ룬ÍⲿÊä³ö£¨·½ÏòÏà¶ÔÓÚÉ豸£©
ÿ¸ö²å¿×¶¼Î¨Ò»µÄID±àºÅ£¬
É豸µÄÊý¾Ýͨ¹ýÄÚǶÊä³ö²å¿×Êä³öµ½¼ÆËã»ú£¬²»ÊÇÖ±½Óµ½PC,¶øÊÇͨ¹ýÐéÄâÍⲿÊäÈë²å¿×Á¬½Ó */
/* MIDI Streaming Interface Header Descriptor */
0x07, //ÀàÌØÊâMS½Ó¿ÚÍ·ÃèÊö·ûµÄ×Ö½ÚÊý´óС----Í·ÃèÊö·û
0x24, //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ0x24
0x01, //ÃèÊö·û×ÓÀà
0x00,
0x01, //×ÓÀà°æ±¾£¬1.0
0x41,
0x00, //ÀàÌØÊâÃèÊö×ܳ¤¶È0x0041 //MIDI IN Jack Descriptor(Embedded) ÄÚǶIN½Ó¿Ú
0x06, //MIDIÊäÈë²å¿×ÃèÊö·û
0x24, //ÀàÌØÊâ½Ó¿Ú
0x02, //MIDI_IN_JACK×ÓÀà0x02
0x01, //EMBEDDED²å¿×Àà
0x01, //¸Ã²å¿ÚµÄID-------------------1
0x00, //δÓà //MIDI IN Jack Descriptor (External) ÍⲿIN½Ó¿Ú
0x06, //MIDIÊäÈë²å¿×ÃèÊö·û
0x24, //ÀàÌØÊâ½Ó¿Ú
0x02, //MIDI_IN_JACK×ÓÀà
0x02, //EXTERNAL²å¿×Àà
0x02, //¸Ã²å¿ÚµÄID-------------------2
0x00, //δÓà //MIDI OUT Jack Descriptor ÄÚǶOUT½Ó¿Ú
0x09, //MIDIÊäÈë²å¿×ÃèÊö·û
0x24, //ÀàÌØÊâ½Ó¿Ú
0x03, //MIDI_OUT_JACK×ÓÀà
0x01, //EMBEDDED²å¿×Àà
0x03, //¸Ã²å¿ÚµÄID------------------3
0x01, //¸Ã²å¿ÚµÄÊäÈëÒý½ÅÊý
0x02, //Á¬½Ó¸ÃÒý½ÅËùÔÚʵÌåµÄID-----ÍⲿIN²å¿×---ÐéÄâÁ¬½ÓÆðÀ´
0x01, //Á¬½Óµ½¸ÃʵÌåÊä³ö½ÅµÄÊäÈë½ÅµÄ±àºÅ
0x00, //δÓà //MIDI OUT Jack Descriptor (External) ÍⲿOUT½Ó¿Ú
0x09, //MIDIÊäÈë²å¿×ÃèÊö·û
0x24, //ÀàÌØÊâ½Ó¿Ú
0x03, //MIDI_OUT_JACK×ÓÀà
0x02, //EXTERNAL²å¿×Àà
0x04, //¸Ã²å¿ÚµÄID------------------4
0x01, //¸Ã²å¿ÚµÄÊäÈëÒý½ÅÊý
0x01, //¸ÃÒý½ÅËùÔÚʵÌåµÄID--------ÄÚǶÊäÈë²å¿×
0x01, //Á¬½Óµ½¸ÃʵÌåÊä³ö½ÅµÄÊäÈë½ÅµÄ±àºÅ
0x00, /***************************¶ËµãÃèÊö·ûºÍÀàÌØÊâ¶ËµãÃèÊö·û£¨MS£©*********************
ÿ¸ö±ê×¼µÄÅúÁ¿Êý¾Ý¶ËµãÃèÊö·ûºóÃæ¸ú×ÅÒ»¸öÀàÌØÊâÊý¾Ý¶ËµãÃèÊö·û*********************/
/* Endpoint Descriptor 03 3 Out, Bulk, 64 bytes */
0x09, //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x05, //¶ËµãÃèÊö·ûÀàÐͱàºÅ
0x03, //3 out bEndpointAddress
0x02, //ʹÓõĴ«ÊäÀàÐÍ£ºÅúÁ¿´«ÊäBULK
0x40, //¸Ã¶ËµãÖ§³ÖµÄ×î´ó°ü³ß´ç£¬64×Ö½Ú
0x00,
0x00, //ÖжÏɨÃèʱ¼ä£¬ÎÞЧ//bInterval
0x00, //bRefresh
0x00, //bSynchAddress /* Unrecognized Audio Class-Specific Descriptor */
0x05, //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x25, //Unrecognized Audio Class-Specific
0x01,
0x01,
0x01, /* Endpoint Descriptor 84 4 In, Bulk, 64 bytes */
0x09, //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x05, //¶ËµãÃèÊö·ûÀàÐͱàºÅ
0x84, //4 IN bEndpointAddress
0x02, //ʹÓõĴ«ÊäÀàÐÍ£ºÅúÁ¿´«ÊäBULK
0x40, //¸Ã¶ËµãÖ§³ÖµÄ×î´ó°ü³ß´ç£¬64×Ö½Ú
0x00,
0x00, //ÖжÏɨÃèʱ¼ä£¬ÎÞЧ0x0A//bInterval
0x00, //bRefresh
0x00, //bSynchAddress /* Unrecognized Audio Class-Specific Descriptor */
0x05, //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
0x25, //Unrecognized Audio Class-Specific
0x01,
0x01,
0x03 };

(3)其中的4个端点地址的设置需要研究下,

链接:

stm32 usb数据缓冲区疑问

http://blog.sina.com.cn/s/blog_640029b30100vwfp.html

#define BTABLE_ADDRESS      (0x00)
/* EP0 */
/* rx/tx buffer base address */
//#define ENDP0_RXADDR (0x18)
//#define ENDP0_TXADDR (0x58)
#define ENDP0_RXADDR (0x40)
#define ENDP0_TXADDR (0x80) /* EP1 */
/* tx buffer base address */
#define ENDP1_TXADDR (0xC0) //ENDP0_TXADDR+0x40¿ªÊ¼
//#define ENDP1_RXADDR (0x130+0x40) /* EP2 */
/* rx buffer base address */
#define ENDP2_RXADDR (0xE0)
//#define ENDP2_TXADDR (0x170+0x40) /* EP3 RX*/
/* tx buffer base address */
//#define ENDP3_TXADDR (0x210)
#define ENDP3_RXADDR (0x100) /* EP4 TX*/
/* tx buffer base address */
#define ENDP4_TXADDR (0x100+0x40)
//#define ENDP4_RXADDR (0x250+0x40)

(4)对于USB HID的理解参考以下博文:

2--STM32+USB移植+HID 与AUDIO类MIDI设备组成的复合设备(原创)的更多相关文章

  1. 转载 STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发  本文转载自 https://www.cnblogs.com/xingboy/p/9913963.html 这里我主要说一 ...

  2. STM32 USB开发(三) 基于F105RBT6核心板开发的自定义HID收发(FS)

    硬件设计 该核心板的USB插口有两个,一个是用于USB Slave的,可以用来做HID设备,把模拟STM32模拟为U盘等:另一个是USB Host设备,可以对插上的U盘的数据进行读写. 图中J2是Mi ...

  3. STM32 USB 问题汇总(转)

    源:STM32 USB 问题汇总 汇总1:STM32的USB例程修改步骤,来自http://blog.csdn.net/cy757/archive/2010/01/01/5117610.aspx 以下 ...

  4. ucos实时操作系统学习笔记——操作系统在STM32的移植

    使用ucos实时操作系统是在上学的时候,导师科研项目中.那时候就是网上找到操作系统移植教程以及应用教程依葫芦画瓢,功能实现也就罢了,没有很深入的去研究过这个东西.后来工作了,闲来无聊就研究了一下这个只 ...

  5. STM32 USB虚拟串口(转)

    源:STM32 USB虚拟串口 串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出.很多本本人群,更是深有体会,不准备一个USB转串口工具就没办法进行开发.本章节来简单概述STM32低端芯片 ...

  6. STM32 USB虚拟串口

    串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出.很多本本人群,更是深有体会,不准备一个USB转串口工具就没办法进行开发.本章节来简单概述STM32低端芯片上的USB虚拟串口的移植.在官方 ...

  7. STM32 USB Virtual COM

    STM32 USB Virtual COM USB转串口的功能实现   这次讲的是如何实现USB转串口功能的实现.首先看看工程的布局吧: 我们主要要介绍的文件的在USB_User这个组文件.从上面的截 ...

  8. STM32 USB转串口驱动 Virtual COM Port Driver(V1.3.1)

    将stm32的USB口接到PC端后,PC端会要求安装一个STM32 USB Virtual COM Port Driver,然后就可以用串口调试助手对其操作了

  9. usb的hid鼠标键盘报告描述符(五)

    title: usb的hid鼠标键盘报告描述符 tags: linux date: 2018/12/20/ 18:05:08 toc: true --- usb的hid鼠标键盘报告描述符 https: ...

随机推荐

  1. 看到一个简单的背单词java程序的设计,收藏下

    https://blog.csdn.net/qq_40605167/article/details/81023836

  2. 微信小程序自定义TabBar

    项目中需要根据用户角色控制TabBar中各Item的显示和隐藏,然而小程序自带TabBar没有提供隐藏某个item的功能,只好自己动手写了一个. 1.wxml文件 <view class=&qu ...

  3. Docker 学习新手笔记:从入门到放弃

    本文记录的是作为一个新手,从了解 Docker 是什么.Docker 技术包含哪些概念到上手使用.安装以及发布 Docker 镜像的整个过程.作者在学习过程中参阅了诸多文档和教程,在此一并感谢,与此同 ...

  4. 删除单链表节点,时间复杂度为O(1)

    一个编程练习,删除单链表一个节点,且时间复杂度控制在O(1)内. 1.核心操作代码如下: struct ListNode { int m_data; ListNode *m_pNext; }; voi ...

  5. QT自定义控件系列(二) --- Loading加载动画控件

    本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

  6. Knut重排算法

    /// <summary> /// 这是Knut重排算法的实现 /// </summary> /// <param name="number"> ...

  7. Findout之为什么公司内部不能使用SSH协议连接外网服务器

    今天在公司学习Linux的过程中,想试着像在Windows中操作Github一样对代码进行克隆,只不过是使用命令行的方式.根据一篇博文(Linux下初次使用Github配置)进行了配置,当我进行到第二 ...

  8. [转]EOS智能合约 & 私链激活 & 基本操作

    链接:https://www.jianshu.com/p/90dea623ffdf 简介 本篇文章,将跟大家介绍eos私链的激活.基础智能合约的安装,以及为大家演示转账等基础操作.还没有安装eos私链 ...

  9. mysql数据库的增量备份和全备

    还有一种简单的方法 参考 https://blog.csdn.net/u010098331/article/details/50932064 (注意:5.6版本以上新加了gtid 功能,gtid开启之 ...

  10. 《Java编程思想》读书笔记-类与对象

    欢迎各位读者关注我的微信公众号,共同探讨Java相关技术.生命不止,学习不休! 也许你慢慢地对程序有了这样的认识:程序只是一些列带有方法的对象的组合,这些方法以其它对象为参数,可在任何地方返回,并发送 ...