关于stm32USB HID触摸屏前面的内容大家可以参考我之前写的两个博客,是一步一步过渡过来的
使用stm32配置自定义的HID设备stm32 USB HID单点触摸屏上报安卓触摸信号

  • 使用stm32的usb,配置成HID模式,并上报数据,模拟触摸,在实现完第一个手指的触摸之后实现第二个手指其实也很简单了,主要还是修改HID报告描述符,通过报告描述符告诉接收方你会上报几个手指,对应的该怎么去解析你上报的数据了,因此总结起来,只需要修改两处地方即可,1、修改HID报告描述符;2、修改数据通讯部分上报的数据内容
  • 之前我们已经实现了单点触摸,(不会的同学可以看我之前的博客stm32 USB HID单点触摸屏上报安卓触摸信号),我们在此基础上修改,需要注意的是,多点触摸在win7系统上没有用,反正在我电脑上是没用的,需要插到安卓上才有用!
  • 修改HID报告描述符
    修改HID报告描述符需要根据HID报告描述符的语法格式来修改,并不是随意的修改,如果HID语法出错,下载完程序之后,使用usblyzer去抓数据,在上报完HID描述符之后,就出错了,后面上报的数据均不会响应,因此HID报告描述符必须符合对应的规则,那么具体规则是怎样的呢,我也没找到对应的详细参考,我是看别人的报告描述符,然后看的多了,大概也就懂需要有哪些注意事项了,比如一个COLLECTION必须与End Collection匹配,就像c语言里面的“{”和“}”一样等等,大家实在不懂就去看看别人的吧,看得多了也就大概会了,下面是HID报告描述符出错时usblyzer的情况
  • android触摸区域大于显示区域 安卓触摸显示_单片机

  • HID描述符没有错误的话,上报数据在usblyzer可以看到
  • android触摸区域大于显示区域 安卓触摸显示_usb_02

  • 这里我就直接把正确的报告描述符丢出来供大家参考
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE]  __ALIGN_END =
{
	//第一个触控点配置
	//其实第一个点和第二个点配置基本差不多,主要是在上报数据的时候的第一字节需要注意
	//上报数据的第一个字节
	//bit7: confidence触摸是否可信 1可信 0不可信(对于安卓不起作用 电脑起作用)
	//bit6-bit2: 触控identifice身份指明是哪一个手的触控 注意上报多点触控的时候要不一样!!!
	//bit1: Range数据范围 一般为1
	//bit0: 按键状态 1按下 0松开
    0x05, 0x0d,                    // USAGE_PAGE (Digitizers)
    0x09, 0x04,                    // USAGE (Touch Screen)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x22,                    //   USAGE (Finger)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x09, 0x42,                    //     USAGE (Tip Switch)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x95, 0x01,                    //     REPORT_COUNT (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x09, 0x32, 				   //     Usage (In Range)
	0x15, 0x00, 				   //     Logical Minimum (0)
	0x25, 0x01, 				   // 	  Logical Maximum (1)
	0x81, 0x02,				   	   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x51,				       //     Usage (Contact Identifier)
	0x75, 0x05,				       //     Report Size (5)
	0x95, 0x01,				       //     Report Count (1)
	0x16, 0x00, 0x00, 			   //     Logical Minimum (0)
	0x26, 0x10, 0x00, 			   //     Logical Maximum (16)
	0x81, 0x02,  				   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x47,  				   //     Usage (Confidence)
	0x75, 0x01,  				   //     Report Size (1)
	0x95, 0x01,  				   //     Report Count (1)
	0x15, 0x00,   				   //     Logical Minimum (0)
	0x25, 0x01,  				   //     Logical Maximum (1)
	0x81, 0x02, 				   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x05, 0x01, 				   //     Usage Page (Generic Desktop)
	0x09, 0x30,  				   //     Usage (X)
	0x75, 0x10,   				   //     Report Size (16)
	0x95, 0x01,  				   //     Report Count (1)
	0x55, 0x0D,  				   //     Unit Exponent (-3)
	0x65, 0x33, 				   //     Unit (Eng Lin: in^3)
	0x35, 0x00,  				   //     Physical Minimum (0)
	0x46, 0x60, 0x17, 			   //     Physical Maximum (5984)
	0x26, 0xFF, 0x0F,   		   //     Logical Maximum (4095)
	0x81, 0x02,				   	   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x31,  				   //     Usage (Y)
	0x75, 0x10, 				   //     Report Size (16)
	0x95, 0x01,  				   //     Report Count (1)
	0x55, 0x0D,				       //     Unit Exponent (-3)
	0x65, 0x33, 				   //     Unit (Eng Lin: in^3)
	0x35, 0x00, 				   //     Physical Minimum (0)
	0x46, 0x26, 0x0E, 			   //     Physical Maximum (3622)
	0x26, 0xFF, 0x0F,  			   //     Logical Maximum (4095)
	0x81, 0x02,     			   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0xC0,    				       //   End Collection 
	
	//第二个触控点配置
    0x05, 0x0d,                    // 	USAGE_PAGE (Digitizers)
	0x09, 0x22,                    //   USAGE (Finger)
    0xa1, 0x01,                    // 	COLLECTION (Application)
    0x09, 0x42,                    //     USAGE (Tip Switch)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x95, 0x01,                    //     REPORT_COUNT (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x09, 0x32, 				   //     Usage (In Range)
	0x15, 0x00, 				   //     Logical Minimum (0)
	0x25, 0x01, 				   // 	  Logical Maximum (1)
	0x81, 0x02,				   	   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x51,				       //     Usage (Contact Identifier)
	0x75, 0x05,				       //     Report Size (5)
	0x95, 0x01,				       //     Report Count (1)
	0x16, 0x00, 0x00, 			   //     Logical Minimum (0)
	0x26, 0x10, 0x00, 			   //     Logical Maximum (16)
	0x81, 0x02,  				   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x47,  				   //     Usage (Confidence)
	0x75, 0x01,  				   //     Report Size (1)
	0x95, 0x01,  				   //     Report Count (1)
	0x15, 0x00,   				   //     Logical Minimum (0)
	0x25, 0x01,  				   //     Logical Maximum (1)
	0x81, 0x02, 				   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x05, 0x01, 				   //     Usage Page (Generic Desktop)
	0x09, 0x30,  				   //     Usage (X)
	0x75, 0x10,   				   //     Report Size (16)
	0x95, 0x01,  				   //     Report Count (1)
	0x55, 0x0D,  				   //     Unit Exponent (-3)
	0x65, 0x33, 				   //     Unit (Eng Lin: in^3)
	0x35, 0x00,  				   //     Physical Minimum (0)
	0x46, 0x60, 0x17, 			   //     Physical Maximum (5984)
	0x26, 0xFF, 0x0F,   		   //     Logical Maximum (4095)
	0x81, 0x02,				   	   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0x09, 0x31,  				   //     Usage (Y)
	0x75, 0x10, 				   //     Report Size (16)
	0x95, 0x01,  				   //     Report Count (1)
	0x55, 0x0D,				       //     Unit Exponent (-3)
	0x65, 0x33, 				   //     Unit (Eng Lin: in^3)
	0x35, 0x00, 				   //     Physical Minimum (0)
	0x46, 0x26, 0x0E, 			   //     Physical Maximum (3622)
	0x26, 0xFF, 0x0F,  			   //     Logical Maximum (4095)
	0x81, 0x02,     			   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
	0xC0,    				       //   End Collection 
	0xC0, 					       // End Collection
};

根据这个报告描述符上报对应的数据,如果想要让电脑或者安卓正确识别,那么上报的数据肯定是需要遵循HID报告描述符的内容的。
我们上述报告描述符对应的数据格式如下
第1字节:触摸1 标志字节(详见后面描述)
第2字节:触摸1 x坐标的低八位
第3字节:触摸1 x坐标的高八位
第4字节:触摸1 y坐标的低八位
第5字节:触摸1 y坐标的高八位
第6字节: 触摸2 标志字节(详见后面描述)
第7字节: 触摸2 x坐标的低八位
第8字节: 触摸2 x坐标的高八位
第9字节: 触摸2 y坐标的低八位
第10字节:触摸2 y坐标的高八位

标志字节组成:
bit7: confidence触摸是否可信 1可信 0不可信(对于安卓不起作用 电脑起作用)
bit6-bit2: 触控identifice身份指明是哪一个手的触控 注意上报多点触控的时候要不一样!!!
bit1: Range数据范围 一般为1
bit0: 按键状态 1按下 0松开

对应主函数如下

uint16_t x1=0,y1=0;
uint16_t x2=0,y2=0;
uint8_t usb_send_buf[10]={0x83,0xFF,0x03,0xFF,0x03,0x87,0xFF,0x06,0xFF,0x06};

  while (1)
  {
//计算中心点坐标
		 x1=4096*1/4-1;
		 y1=4096*1/4-1;
		 
		 x2=4096*3/4-1;
		 y2=4096*3/4-1;
		  
		 //计算起始坐标
		 x1=x1-200;
		 y1=y1-200;
		 
		 x2=x2+200;
		 y2=y2+200;
	 
	   //正方形手势
		for(i=0;i<200;i++)
		{
		  x1+=2;
		  usb_send_buf[0]=0x83;
		  usb_send_buf[1]=x1%256;
		  usb_send_buf[2]=x1/256;
		  usb_send_buf[3]=y1%256;
		  usb_send_buf[4]=y1/256;
			
		  x2-=2;
		  usb_send_buf[5]=0x87;
		  usb_send_buf[6]=x2%256;
		  usb_send_buf[7]=x2/256;
		  usb_send_buf[8]=y2%256;
		  usb_send_buf[9]=y2/256;
		  USBD_HID_SendReport(&hUsbDeviceFS,usb_send_buf,sizeof(usb_send_buf));
		  HAL_Delay(3);
		}
		for(i=0;i<200;i++)
		{
		  y1+=2;
		  usb_send_buf[0]=0x83;
		  usb_send_buf[1]=x1%256;
		  usb_send_buf[2]=x1/256;
		  usb_send_buf[3]=y1%256;
		  usb_send_buf[4]=y1/256;
			
		  y2-=2;
		  usb_send_buf[5]=0x87;
		  usb_send_buf[6]=x2%256;
		  usb_send_buf[7]=x2/256;
		  usb_send_buf[8]=y2%256;
		  usb_send_buf[9]=y2/256;
		  USBD_HID_SendReport(&hUsbDeviceFS,usb_send_buf,sizeof(usb_send_buf));
		  HAL_Delay(3);
		}
		for(i=0;i<200;i++)
		{
		  x1-=2;
		  usb_send_buf[0]=0x83;
		  usb_send_buf[1]=x1%256;
		  usb_send_buf[2]=x1/256;
		  usb_send_buf[3]=y1%256;
		  usb_send_buf[4]=y1/256;
			
		  x2+=2;
		  usb_send_buf[5]=0x87;
		  usb_send_buf[6]=x2%256;
		  usb_send_buf[7]=x2/256;
		  usb_send_buf[8]=y2%256;
		  usb_send_buf[9]=y2/256;
		  USBD_HID_SendReport(&hUsbDeviceFS,usb_send_buf,sizeof(usb_send_buf));
		  HAL_Delay(3);
		}
		for(i=0;i<200;i++)
		{
		  y1-=2;
		  usb_send_buf[0]=0x83;
		  usb_send_buf[1]=x1%256;
		  usb_send_buf[2]=x1/256;
		  usb_send_buf[3]=y1%256;
		  usb_send_buf[4]=y1/256;
			
		  y2+=2;
		  usb_send_buf[5]=0x87;
		  usb_send_buf[6]=x2%256;
		  usb_send_buf[7]=x2/256;
		  usb_send_buf[8]=y2%256;
		  usb_send_buf[9]=y2/256;
		  USBD_HID_SendReport(&hUsbDeviceFS,usb_send_buf,sizeof(usb_send_buf));
		  HAL_Delay(3);
		}
		
		//松开按键
		usb_send_buf[0]=0x82;
		usb_send_buf[5]=0x86;
		USBD_HID_SendReport(&hUsbDeviceFS,usb_send_buf,sizeof(usb_send_buf));
	    HAL_Delay(7);
	}
 }

安卓进行相应设置,打开开发者模式,然后打开触摸轨迹,编译下载对应的程序,将设备插在安卓上,可以在安卓上看到对应的触摸轨迹为两个矩形