STM32模拟USB多点触控屏

news/2024/11/17 22:47:15/

STM32模拟USB多点触控屏

开发准备

  • STM32的USB官方例程库JoyStickMouse
  • STM32F103RC
  • Windows7

代码修改
1.usb_pwr.c

RESULT PowerOn(void)
{u16 wRegVal;                     //USB_Cable_Config(ENABLE);//这里由于硬件问题用不到,注释/*** CNTR_PWDN = 0 ***/wRegVal = CNTR_FRES;_SetCNTR(wRegVal);     /*** CNTR_FRES = 0 ***/wInterrupt_Mask = 0;_SetCNTR(wInterrupt_Mask);/*** Clear pending interrupts ***/_SetISTR(0);/*** Set interrupt mask ***/wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;_SetCNTR(wInterrupt_Mask);     return USB_SUCCESS;
}

2.usb_proc.c

void Joystick_Reset(void)
{/* Set Joystick_DEVICE as not configured */pInformation->Current_Configuration = 0;pInformation->Current_Interface = 0;/* the default Interface *//* Current Feature initialization */pInformation->Current_Feature = Joystick_ConfigDescriptor[7];SetBTABLE(BTABLE_ADDRESS);/* Initialize Endpoint 0 */SetEPType(ENDP0, EP_CONTROL);SetEPTxStatus(ENDP0, EP_TX_STALL);SetEPRxAddr(ENDP0, ENDP0_RXADDR);SetEPTxAddr(ENDP0, ENDP0_TXADDR);Clear_Status_Out(ENDP0);SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);SetEPRxValid(ENDP0);/* Initialize Endpoint In 1 */SetEPType(ENDP1, EP_INTERRUPT); //初始化为中断端点类型SetEPTxAddr(ENDP1, ENDP1_TXADDR); //设置发送数据的地址SetEPTxCount(ENDP1, 14); //设置发送的长度,这里由于使用的两点触控的触控屏需要发送的数据为14Bytes一次SetEPTxStatus(ENDP1, EP_TX_NAK); //设置端点处于忙状态/* Initialize Endpoint Out 1 */SetEPRxAddr(ENDP1, ENDP1_RXADDR); //设置接收数据的地址SetEPRxCount(ENDP1, 2);  //设置接收长度SetEPRxStatus(ENDP1, EP_RX_VALID); //设置端点有效,可以接收数据bDeviceState = ATTACHED;/* Set this device to response on default address */SetDeviceAddress(0);
}

由于需要枚举的是多点触控屏,需要处理Get_Report和Set_Report,虽然有些人说Set_Report不需要处理,但是我还是顺手处理掉了。

/*******************************************************************************
添加上获取HID描述符和报告描述符函数
*******************************************************************************/
ONE_DESCRIPTOR Test_Hid_Descriptor =                                {                                                                 
    (u8*)Joystick_ConfigDescriptor + Test_OFF_HID_DESC,             
    JOYSTICK_SIZ_HID_DESC                                           };ONE_DESCRIPTOR Test_Report_Descriptor =                             {                                                                 
    (u8 *)TestReportDescriptor,                                     
    Test_ReportDescriptor_Size                                      };    u8 *Test_GetHIDDescriptor(u16 Length)
{
    return Standard_GetDescriptorData(Length, &Test_Hid_Descriptor);
}u8 *Test_GetReportDescriptor(u16 Length)
{
    return Standard_GetDescriptorData(Length, &Test_Report_Descriptor);
}/*******************************************************************************
这里用来处理Get_Report Set_Report
*******************************************************************************/
u8 Report_Buffer[2] = {0x02, 0x02}; //Report_Buffer[0]为FeatureID,
                                    //Report_Buffer[1]为最大触控点数u8 *Joystick_GetReport(u16 Length)  //处理Get_Report
{
    if(Length == 0)
    {
        pInformation->Ctrl_Info.Usb_wLength = 2;
        return NULL;
    }
    return  &Report_Buffer[pInformation->Ctrl_Info.Usb_wOffset];
}u8 *Joystick_SetReport(u16 Length)//处理Set_Report
{
    if(Length == 0)
    {
        pInformation->Ctrl_Info.Usb_wLength = 2;
        return NULL;
    }
    return &Report_Buffer[pInformation->Ctrl_Info.Usb_wOffset];
}RESULT Joystick_Data_Setup(u8 RequestNo)
{u8 *(*CopyRoutine)(u16);CopyRoutine = NULL;if ((RequestNo == GET_DESCRIPTOR)
      && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
      && (pInformation->USBwIndex0 < 3)){
    if (pInformation->USBwValue1 == REPORT_DESCRIPTOR)
    {
        CopyRoutine = Test_GetReportDescriptor;
    }
    else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)
    {
        CopyRoutine = Test_GetHIDDescriptor;
    }} /* End of GET_DESCRIPTOR *//*** GET_PROTOCOL ***/else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
           && RequestNo == GET_PROTOCOL){
    CopyRoutine = Joystick_GetProtocolValue;}/******************************************************************
Add Handle Get_Report and Set_Report CTL:
******************************************************************/else if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))){
    switch(RequestNo)
    {
        case GET_REPORT:
            CopyRoutine = Joystick_GetReport;
            break;        case SET_REPORT:
            CopyRoutine = Joystick_SetReport;
            break;        default:
            break;
    }}if (CopyRoutine == NULL){
    return USB_UNSUPPORT;}pInformation->Ctrl_Info.CopyData = CopyRoutine;pInformation->Ctrl_Info.Usb_wOffset = 0;(*CopyRoutine)(0);return USB_SUCCESS;
}

3.usb_conf.h

//地址为32位对其,位4的倍数,不能超过 bMaxPacketSize
/* EP0  */
/* rx/tx buffer base address */
#define ENDP0_RXADDR        (0x40)
#define ENDP0_TXADDR        (0x80)/* EP1  */
/* rx/tx buffer base address */
#define ENDP1_RXADDR        (0xc0)
#define ENDP1_TXADDR        (0x100)

4.usb_desc.h

#define JOYSTICK_SIZ_CONFIG_DESC                41  //配置描述符的大写改为41,即0x29
#define Test_ReportDescriptor_Size              202 //触控屏报表描述符长度
#define Test_OFF_HID_DESC                       18  //触控屏HID描述符的偏移量extern const u8 TestReportDescriptor[Test_ReportDescriptor_Size];//extern一下

5.usb_desc.c

const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =
{
/***************配置描述符***********************/0x09,      //bLength字段USB_CONFIGURATION_DESCRIPTOR_TYPE,     //bDescriptorType字段JOYSTICK_SIZ_CONFIG_DESC&0xff,         //wTotalLength字段(JOYSTICK_SIZ_CONFIG_DESC>>8)&0xff,0x01,                                  //bNumInterfaces字段0x01,                                  //bConfiguration字段0x00,                                  //iConfigurationz字段0x80,                                  //bmAttributes字段0x20,                                  //bMaxPower字段
/* 9 *//*******************第一个接口描述符*********************/0x09,                                  //bLength字段USB_INTERFACE_DESCRIPTOR_TYPE,         //bDescriptorType字段0x00,                                  //bInterfaceNumber字段0x00,                                  //bAlternateSetting字段0x02,                                  //bNumEndpoints字段0x03,                                  //bInterfaceClass字段0x00,                                  //bInterfaceSubClass字段0x00,                                  //bInterfaceProtocol字段0x00,                                  //iConfiguration字段
/* 18 *//******************HID描述符************************/
0x09,                                   //bLength字段
0x21,                                   //bDescriptorType字段
0x01,                                   //bcdHID字段
0x01,
0x00,                                   //bCountyCode字段
0x01,                                   //bNumDescriptors字段
0x22,                                   //bDescriptorType字段
Test_ReportDescriptor_Size&0xFF,
(Test_ReportDescriptor_Size>>8)&0xFF,
/* 27 *//**********************输入端点描述符***********************/0x07,                                 //bLength字段USB_ENDPOINT_DESCRIPTOR_TYPE,         //bDescriptorType字段0x81,                                 //bEndpointAddress字段0x03,                                 //bmAttributes字段0x10,                                 //wMaxPacketSize字段0x00,0x0A,                                 //bInterval字段
/* 34 *//**********************输出端点描述符***********************/0x07,                                 //bLength字段USB_ENDPOINT_DESCRIPTOR_TYPE,         //bDescriptorType字段0x01,                                 //bEndpointAddress字段0x03,                                 //bmAttributes字段0x10,                                 //wMaxPacketSize字段0x00,0x0A,                                 //bInterval字段
/* 41 */
const u8 TestReportDescriptor[Test_ReportDescriptor_Size] = 
{/* 多点触控设备 */0x05, 0x0d,// USAGE_PAGE (Digitizers)0x09, 0x04,// USAGE (Touch Screen)0xa1, 0x01,// COLLECTION (Application)0x85, 0x01,//REPORTID_MTOUCH, // REPORT_ID (Touch)/* 8 *//* 第一点 */ /* 手指和z轴 */0x09, 0x22,// USAGE (Finger)0xa1, 0x02,// COLLECTION (Logical)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)0x81, 0x02,// INPUT (Data,Var,Abs)0x95, 0x06,// REPORT_COUNT (6)0x81, 0x01,// INPUT (Cnst,Ary,Abs)/* 32 *//* 手指ID */    0x75, 0x08,// REPORT_SIZE (8)0x09, 0x51,// USAGE ( Contact Identifier)0x25, 0xFF,//  LOGICAL_MAXIMUM (255)0x95, 0x01,// REPORT_COUNT (1)0x81, 0x02,// INPUT (Data,Var,Abs)/* 42 *//* X和Y */0x05, 0x01,// USAGE_PAGE (Generic Desk)0x16, 0x00,0x00,//HID_LogicalMinS (0)0x26, 0x56, 0x05,// LOGICAL_MAXIMUM (1366)0x75, 0x10,// REPORT_SIZE (16)0x55, 0x00,// UNIT_EXPONENT (0)0x65, 0x00,// UNIT (00)0x09, 0x30,// USAGE (X)0x36, 0x00,0x00,// PHYSICAL_MINIMUM (0)0x46, 0x56, 0x05,// PHYSICAL_MAXIMUM (1366)0x95, 0x01,// REPORT_COUNT (1)0x81, 0x02,// INPUT (Data,Var,Abs)0x26, 0x00, 0x03,// LOGICAL_MAXIMUM (4095)0x46, 0x00, 0x03,// PHYSICAL_MAXIMUM (4095)0x09, 0x31,// USAGE (Y)0x81, 0x02,// INPUT (Data,Var,Abs)0xc0,      // END_COLLECTION/* 79 *//* 第二点 *//* 手指和z轴 */0x05, 0x0d,// USAGE_PAGE (Digitizers)0x09, 0x22,// USAGE (Finger)0xa1, 0x02,// COLLECTION (Logical)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)0x81, 0x02,// INPUT (Data,Var,Abs)0x95, 0x06,// REPORT_COUNT (6)0x81, 0x01,// INPUT (Cnst,Ary,Abs)/* 105 *//* 手指ID */0x75, 0x08,// REPORT_SIZE (8)0x09, 0x51,// USAGE ( Contact Identifier)0x95, 0x01,// REPORT_COUNT (1)0x25, 0xFF,// LOGICAL_MAXIMUM (255) 0x81, 0x02,// INPUT (Data,Var,Abs)/* 115 *//* X和Y */0x05, 0x01,// USAGE_PAGE (Generic Desk..0x26, 0x56, 0x05, // LOGICAL_MAXIMUM (1366)0x75, 0x10,// REPORT_SIZE (16)0x55, 0x00,// UNIT_EXPONENT (0)0x65, 0x00,// UNIT (0)0x09, 0x30,// USAGE (X)0x36, 0x00,0x00,// PHYSICAL_MINIMUM (0)0x46, 0x56, 0x05,// PHYSICAL_MAXIMUM (1366)0x81, 0x02,// INPUT (Data,Var,Abs)0x26, 0x00, 0x03,0x46, 0x00, 0x03,// PHYSICAL_MAXIMUM (0)0x09, 0x31,// USAGE (Y)0x81, 0x02,// INPUT (Data,Var,Abs)0xc0, //END_COLLECTION/* 147 *//* 实际点数 */0x05, 0x0d,// USAGE_PAGE (Digitizers)0x09, 0x54,// USAGE (Actual count)0x95, 0x01,// REPORT_COUNT (1)0x75, 0x08,// REPORT_SIZE (8)0x15, 0x00,// LOGICAL_MINIMUM (0)0x25, 0x08,// LOGICAL_MAXIMUM (8)0x81, 0x02,// INPUT (Data,Var,Abs)/* 161 *//* 硬件支持点数 */0x85, 0x02,// REPORT_ID (Feature)0x75, 0x08,// REPORT_SIZE (8)0x95, 0x01,// REPORT_COUNT (1)0x15, 0x01,// LOGICAL_MINIMUM (1)0x25, 0x08,// LOGICAL_MAXIMUM (8)0x09, 0x55,// USAGE(Maximum Count)0xB1, 0x02,// FEATURE (Data,Var,Abs)0xc0,       // END_COLLECTION/* 176 *//* 上位机特性设定 */0x09, 0x0E,// USAGE (Device Configuration)  0xa1, 0x01,// COLLECTION (Application)  0x85, 0x04,// REPORT_ID (Configuration)                0x09, 0x23,// USAGE (Device Settings)                0xa1, 0x02,// COLLECTION (logical)      0x09, 0x52,// USAGE (Device Mode)           0x15, 0x00,// LOGICAL_MINIMUM (0)        0x25, 0x0a,// LOGICAL_MAXIMUM (10)  0x75, 0x08,// REPORT_SIZE (8)           0x09, 0x53,// USAGE (Device Identifier) 0x95, 0x01,// REPORT_COUNT (2)  0xb1, 0x02,// FEATURE (Data,Var,Abs      0xc0,         // END_COLLECTION  0xc0,         // END_COLLECTION/* 202 */
};

效果

枚举成功就可以在系统设备中找到枚举的触控屏设备信息了,这里使用的是Usblyer。

如何测试

void Test_Send(uint8_t *buf, uint16_t len)
{//  对于本代码2点触控每个数据包由14个字节组成分别为//  InReport[0]     设备ID 固定值为TOUCH_REPORT_ID//  InReport[1]     第一点触摸情况 bit1:1有触摸 0没触摸  bit2: 1在范围内  0不在范围内//  InReport[2]     第一点ID  每个点在抬起之前不能改变     0~255//  InReport[3]     第一点X坐标低8位//  InReport[4]     第一点X坐标高8位//  InReport[5]     第一点Y坐标低8位//  InReport[6]     第一点Y坐标高8位//  InReport[7]     第二点触摸情况 bit1:1有触摸 0没触摸  bit2: 1在范围内  0不在范围内//  InReport[8]     第二点ID  每个点在抬起之前不能改变     0~255//  InReport[9]     第二点X坐标低8位//  InReport[10]    第二点X坐标高8位//  InReport[11]    第二点Y坐标低8位//  InReport[12]    第二点Y坐标高8位//  InReport[13]    此数据包中有效的点数static uint8_t i = 0;uint8_t Buffer[14];if(i > 0 && i < 20){Buffer[0]   = 0x01;Buffer[1]   = 0x07;Buffer[2]   = 0x01;Buffer[3]   = 0x88;Buffer[4]   = 0x07;Buffer[5]   = 0x85;Buffer[6]   = 0x04;Buffer[7]   = 0x00;Buffer[8]   = 0x00;Buffer[9]   = 0x00;Buffer[10]  = 0x00;Buffer[11]  = 0x00;Buffer[12]  = 0x00; Buffer[13]  = 0x01;}if(i < 40 && i > 20){Buffer[0]   = 0x01;Buffer[1]   = 0x06;Buffer[2]   = 0x01;Buffer[3]   = 0x88;Buffer[4]   = 0x07;Buffer[5]   = 0x85;Buffer[6]   = 0x04;Buffer[7]   = 0x00;Buffer[8]   = 0x00;Buffer[9]   = 0x00;Buffer[10]  = 0x00;Buffer[11]  = 0x00;Buffer[12]  = 0x00; Buffer[13]  = 0x01;}if(i > 40){Buffer[0]   = 0x01;Buffer[1]   = 0x00;Buffer[2]   = 0x00;Buffer[3]   = 0x00;Buffer[4]   = 0x00;Buffer[5]   = 0x00;Buffer[6]   = 0x00;Buffer[7]   = 0x00;Buffer[8]   = 0x00;Buffer[9]   = 0x00;Buffer[10]  = 0x00;Buffer[11]  = 0x00;Buffer[12]  = 0x00; Buffer[13]  = 0x00;}i++;if(i > 60){i = 0;}UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP1) , 14);SetEPTxValid(ENDP1);return;
}

这份东西还有很多不足的地方,报表那边的逻辑大小是需要对应触控屏的,触点是可以增加的,发送的数据坐标有些问题,目前还在调试中。。。


http://www.ppmy.cn/news/484976.html

相关文章

多点触控参数

简介 为了使用功能强大的多点触控设备&#xff0c;就需要一种方案去上报用户层所需的详细的手指触摸数据。这个文档所描述的多点触控协议可以让内核驱动程序向用户层上报任意多指的数据信息。 使用说明 单点触摸信息是以ABS承载并按一定顺序发送&#xff0c;如BTN_TOUCH、ABS…

C语言易错剖析(1)-数据类型

C语言易错剖析 int8_t、int16_t、int32_t、int64_t、uint8_t、size_t、ssize_t等数据类型 int_t同类 int_t 为一个结构的标注&#xff0c;可以理解为type/typedef的缩写&#xff0c;表示它是通过typedef定义的&#xff0c;而不是一种新的数据类型。因为跨平台&#xff0c;不…

多点触控与单点触控

private ImageView mImageView;private Matrix matrix new Matrix();private Matrix savedMatrix new Matrix();private static final int NONE 0;private static final int DRAG 1;private static final int ZOOM 2;private int mode NONE;// 第一个按下的手指的点priv…

多点触摸处理

接着上文&#xff0c;我们做了一个简陋的下拉刷新控件&#xff0c;目前用到的知识点有 view的滑动view的弹性滑动事件分发机制事件分发机制的两个小问题&#xff08;事件的二次分发&#xff09; 目前这个控件除了简陋一点&#xff0c;没做抽象封装&#xff0c;在单手操作下&a…

多点触控 - MFC

概述 Windows 7 支持用户通过手指接触来管理应用程序&#xff0c;无需使用中间设备。这扩展了平板 PC 基于触笔的功能。与其他指针设备不同&#xff0c;这种新功能允许多个输入事件在不同指针位置同时发生&#xff0c;它还支持复杂的场景&#xff0c;比如通过十个手指或多个并…

多点触控

1.要了解多点触控&#xff0c;我们必须先了解一下View的生命周期&#xff0c;毕竟在Android用的到多点触控的地方&#xff0c;一般都是自定义控件。就像Fragment和Activity都有生命周期一样&#xff0c;View也有自己的生命周期。该生命周期并不直接和展示它的Fragment或者Activ…

多点触摸屏技术

多点触摸屏技术 2006年02月苹果申请了一些多点触摸屏的专利(multipoint)&#xff0c;今天苹果公司提供了完整的iPod产品线&#xff0c;并且引入了带有触摸屏和多点触摸技术的iPod。参见&#xff1a;苹果将发布更便宜更创带无线的新iPod 一年前还感叹QQ的概念QQ版&#xff0c;…

android多点触控的理解

首先多点触控要使用event.getActionMasked()来获取事件&#xff0c;调用情况如下&#xff1a; case MotionEvent.ACTION_DOWN&#xff1a; //第一根手指按下触发&#xff0c;只会触发一次case MotionEvent.ACTION_MOVE&#xff1a; //所有手指的move事件都会触发这个事件case …