STM32H743IIT6+USB3300,USB_HS高速双向HID通讯开发

环境为STM32CUBEMX+MDK5.27

开发目的:实现与电脑的USB_HS高速通讯,通过ULPI接口外接PHY芯片,模式为custom hid。

板子为微雪open743,模块USB3300也是微雪家的,之前单独买了一个USB3300模块搭配自己手里的743核心板(杜邦线连接),发现USB枚举无法正常。无奈之举,买了一块微雪的开发板。项目着急开发程序,板子只能买,全网做USB3300模块也就微雪一家。

开发流程:

1、微雪只提供了USB_HS的HID和MSC例子,其中HID是模拟鼠标功能,与设计需求不符,为了测试板子功能直接烧录完成测试,程序功能正常,能遥杆控制鼠标移动

2、参考微雪的开发方式,用STM32CUBEMX开配置USB_HS和外部PHY芯片接口。STM32CUBEMX配置如下

框里第一个参数影响USB的刷新时间,影响传输速度,最快可以调到0X01

PS:主要的配置就这些,时钟频率我设置满速480MHZ。

3、生成代码,MDK5.27环境。

4、修改代码

分析一下报文,记录一下

这里我说一下这个报文的要素,第一部分你可以理解为报文头;第二部分你可以理解为USB告诉PC机问我要做什么,这里主要告诉PC机我要做一个接收与发送的设备,USAGE~INPUT这里是描述这个USB设备作为输入的时候的数据格式,下一个USAGE~OUTPUT是描述该USB设备输出的数据格式,其中LOGICAL_MINIMUM是指每个字节数据的最小值,LOGICAL_MAXIMUM是指每个字节数据的最大值,REPORT_COUNT是指定每次传输数据最多多少个字节,REPORT_SIZE是指定每次传输数据每个字节的位数;第三部分是结束标志。

============================================================

下面我插入一个对报文描述符进行一个简单的描述:

   

标签解析举例(Usage :0x50, 0x01):

  (Usage Page标签0x0?)0x05=0000 0101 :

  0x05表示前缀,0x01为数据部分,0x05转换成二进制,就是0000 01 01,按照HID类协议5.3 generic item format的定义,这个字节被分成3个部分:

  bit0~bit1代表的是这个前缀后面跟的数据长度,这里就是后面0x01的长度,两位可以表示最大4字节的数据,即bsize

  bit2~bit3代表的是这个前缀的类型,总共可以有三种类型:0=main,1=global,2=local,3=reserved;

  bit4~bit7代表前tag,一般分为input(二进制的1000 00 nn,即bit4~bit7=1000,代表一个tag,bit2~bit3=00,代表main,bit0~bit1=nn,代表这个前缀后面还有nn所代表的数据),output(二进制的 1001 00 nn),feature(1011 00 nn),collection(1010 00 nn),end collection(1100 00 nn)

即:

  0000:Usage Page

  01: bType,全局(bType=0:主项目;bType=1:全局项目;bType=2:区域项目)

  01:bSzie,1字节(bSzie为项目所需数据字节数目,bSzie可为1、2、4,注意bSzie不可为3)

 (Page ID)0x01: 表示该Page为Generalic Desktop Controls(Usage ID 0为保留。ID 1到0x1F为”top level” collection保留,这些ID虽然对于Application不是必须,但可以用于识别通用设备类型)

  

  Usage = (usage page:usage ID):其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。所以“传输的数据”和“操作”只是一事件的两种描述方式。用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage ID(用途识别名),文件universal serial Bus HID Usage Table完整列出所有的usage pages(用途类页)和usage ID(用途识别名),使用者必须遵照文件的规范来声明操作的用途。用途卷标只是报告描述符诸多标签的一个,利用这些卷标取可以清楚完整的描述符操作的用途。

  这里其实说的并不清楚,因为作者有点懒就不细说了,想了解更多的可以百度《圈圈教你玩USB》,这里说的比我好。

程序修改

【1】usbd_custom_hid_if.c

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_HS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
    0x06, 0x00, 0xff,              // USAGE_PAGE (Vendor Defined Page 1)
    0x09, 0x01,                    // USAGE (Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Vendor Usage 1)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x95, 0x40,                    //   REPORT_COUNT (64)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x09, 0x01,                    //   USAGE (Vendor Usage 1)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x95, 0x40,                    //   REPORT_COUNT (64)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};

【2】usbd_conf.h

#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     64U
/*---------- -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE     34U

【3】usbd_customhid.h

#define CUSTOM_HID_EPIN_ADDR                         0x81U
#define CUSTOM_HID_EPIN_SIZE                         0x40U

#define CUSTOM_HID_EPOUT_ADDR                        0x01U
#define CUSTOM_HID_EPOUT_SIZE                        0x40U

5、编译烧写代码

结果:电脑设备管理器没反应

反复插拔USB线,尝试拔掉调试器,偶尔会出现响应,但并不稳定,过一会被断开。头疼了,反复折腾模式,发现无论是虚拟串口还是HID都是如此现象。

6、调试代码,检查细节

STM32CUBEMX经常会生成BUG,对,生成BUG,虐我千百遍。要不是可以省移植USB驱动的功夫,才懒得用

对照了微雪的例子和STM32CUBE文件设置。发现一个有差别的地方,怎么我这生成的程序里打开了GPIOI的时钟,微雪的却没有。

问题原因:cubemx生成的ULPI_DIR引脚是PI11,微雪板子是接到PC2

这这这,ULPI接口的引脚不是固定的吗?还可以有出入?过于相信CUBEMX生成的代码了,惊了。修改了一下程序,再烧写,反应就对了。

然后,在mian.c里加入了测试代码,单上传。

extern USBD_HandleTypeDef hUsbDeviceHS; //外部声明USB的句柄
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t send_buf[64] = {//定义一个USB的发送BUFF
                         1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
                         17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
                         40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64}; 


  while (1)
  {
    /* USER CODE END WHILE */
		USBD_CUSTOM_HID_SendReport(&hUsbDeviceHS, send_buf, sizeof(send_buf));  //第一个参数是USB句柄,生成项目就有了的;第二个参数是发送数据;第三个发送的数据长度
      //HAL_Delay(10);
    /* USER CODE BEGIN 3 */
  }

终于对了。

然后是电脑下发,单片机接收功能的实现。

在usbd_custom_hid_if.c内添加以下代码。

unsigned char USB_Recive_Buffer[64]; //USB接收缓存
unsigned char USB_Received_Count = 0;//USB接收数据计数
//这个函数有原形,找到修改即可。
static int8_t CUSTOM_HID_OutEvent_HS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
     char i;
  
    /*查看接收数据长度*/
    USB_Received_Count = USBD_GetRxCount( &hUsbDeviceHS,CUSTOM_HID_EPOUT_ADDR );  //第一参数是USB句柄,第二个参数的是接收的末端地址;要获取发送的数据长度的话就把第二个参数改为发送末端地址即可
    //printf("USB_Received_Count = %d \r\n",USB_Received_Count);
    
    USBD_CUSTOM_HID_HandleTypeDef   *hhid; //定义一个指向USBD_CUSTOM_HID_HandleTypeDef结构体的指针
    hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceHS.pClassData;//得到USB接收数据的储存地址
    
    for(i=0;i<USB_Received_Count;i++) 
    {
        USB_Recive_Buffer[i]=hhid->Report_buf[i];  //把接收到的数据送到自定义的缓存区保存(Report_buf[i]为USB的接收缓存区)
    } 
  return USBD_OK;
  /* USER CODE END 6 */
}

结果:

基本功能已经完成,还需要找个软件来测试下上传速度。

版权声明:本文为CSDN博主「不爱吃糖的胖子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010396127/article/details/117283108

生成海报
点赞 0

不爱吃糖的胖子

我还没有学会写个人说明!

暂无评论

相关推荐

usb NRZI

usb的编码方式NRZI RZ归零编码 正电平代表逻辑1,负电平代表逻辑0。每传完一次数据,信号回到零电平。 在归零后重新采样,不需要单独的时钟信号,称自同步信号。 NRZ不归零编

单路USB转单/多路串口方案

单路USB转单/多路串口方案 在日常开发或产品设计时,会遇到不少使用串口通讯或者调试的情况,一个串口时使用USB转单路串口则可优雅解决,但若是多个串口时则可能需要占据多个USB口,颇为麻

RT-Thread Studio移植LAN8720A驱动

RTT网络协议栈驱动移植(霸天虎) 1、新建工程 ​ 工程路径不含中文路径名,工程名用纯英文不含任何符号。 2、用CubeMx配置板子外设 2.1、配置时钟 ​ 按照自己板子配置相应时钟。

Lin总线通信在STM32作为主机代码以及从机程序

距离上次做资料准备已经过去六天了。最近在学车,上周末就没有开电脑。这周开始进行了Lin通信的代码整理,目前是可以正常通信的了,采用的是增强型校验方式。后期再进一步跟进研究。。。更新一博,留