网上很多案例都是基于相对位置鼠标的,在手机上不太好计算按钮位置,就想尝试一下绝对位置鼠标,关于绝对位置鼠标,csdn有位大佬已经将整理的很详尽了,这里附上链接:
https://blog.csdn.net/pengranxindong/article/details/143822142
作者:技术宅AI代码控需要修改的两个文件:
一,usbd_hid.c
需要修改的是上述文件里的这一段:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
......
};相对坐标鼠标描述符
//相对坐标格式
//每行开始的第一字节为该条目的前缀,前缀的格式为:
//D7~D4:bTag。D3~D2:bType;D1~D0:bSize。以下分别对每个条目注释。
0x05,0x01, // 是一个全部条目。表示用途页为通用桌面设备
0x09,0x02, // 是一个局部条目。表示用途为鼠标
0xa1,0x01, // 表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION
0x09,0x01, // 是一个局部条目。说明用途为指针集合
0xa1,0x00, // 这是一个主条目,开集合,后面跟的数据0x00表示该集合是一个物理集合,用途由前面的局部条目定义为指针集合。
0x95,0x03, // 这是一个全局条目,说明数据域的数量为三个。
0x75,0x01, // 这是一个全局条目,说明每个数据域的长度为1个bit。
0x05,0x09, // 这是一个全局条目,选择用途页为按键(Button Page(0x09))
0x19,0x01, // 这是一个局部条目,说明用途的最小值为1。实际上是鼠标左键。
0x29,0x03, // 这是一个局部条目,说明用途的最大值为3。实际上是鼠标中键。
0x15,0x00, // 这是一个全局条目,说明返回的数据的逻辑值(就是我们返回的数据域的值啦)最小为0。因为我们这里用Bit来表示一个数据域,因此最小为0。 MAXMIN
0x25,0x01, // 最大为1 MAXNUM
0x81,0x02, // 这是一个主条目,标识上面的3个bits是独立的。
0x95,0x01, // 这是一个全局条目,说明数据域数量为1个
0x75,0x05, // 这是一个全局条目,说明每个数据域的长度为5bit。
0x81,0x03, // //这是一个主条目,输入用,由前面两个全局条目可知,长度为5bit,数量为1个。它的属性为常量(即返回的数据一直是0)。这个只是为了凑齐一个字节(前面用了3个bit)而填充的一些数据而已,所以它是没有实际用途的。
0x95,0x03, // 这是一个全局条目,说明数据域的个数为3个。
0x75,0x08, // 这是一个全局条目,说明数据域的长度为8bit。
0x05,0x01, // 这是一个全局条目,选择用途页为普通桌面Generic Desktop Page(0x01)
0x09,0x30, // 这是一个局部条目,说明用途为X轴
0x09,0x31, // 这是一个局部条目,说明用途为Y轴
0x09,0x38, // 这是一个局部条目,说明用途为滚轴
0x15,0x81, // 这是一个全局条目,说明返回的逻辑最小为-128。
0x25,0x7f, // 这是一个全局条目,说明返回的逻辑最大为127。
0x81,0x06, // 这是一个主条目。标识上面的3个数据是绝对值。
0xc0, // 我们开了两个集合,所以要关两次。bSize为0,所以后面没数据。
0xc0 // END_COLLECTION 绝对坐标鼠标描述符
电脑上可识别,手机无响应:
//每行开始的第一字节为该条目的前缀,前缀的格式为:
//D7~D4:bTag。D3~D2:bType;D1~D0:bSize。以下分别对每个条目注释。
//这是一个全局(bType为1)条目,选择用途页为普通桌面Generic Desktop Page(0x01)
//后面跟一字节数据(bSize为1),后面的字节数就不注释了,
//自己根据bSize来判断。
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
//这是一个局部(bType为2)条目,说明接下来的应用集合用途用于鼠标
0x09, 0x02, // USAGE (Mouse)
//这是一个主(bType为0)条目,开集合,后面跟的数据0x01表示
//该集合是一个应用集合。它的性质在前面由用途页和用途定义为
//普通桌面用的鼠标。
0xa1, 0x01, // COLLECTION (Application) //1byte报告ID +按键(3bit)+填充行(5bit)=1byte ; 坐标(16bits*2个)=4bytes;所以上报数据就是6bytes;
0x85,0x02, // 报告ID(报告ID 0是保留的),多个设备需要添加。
//这是一个局部条目。说明用途为指针集合
0x09, 0x01, // USAGE (Pointer)
//这是一个主条目,开集合,后面跟的数据0x00表示该集合是一个
//物理集合,用途由前面的局部条目定义为指针集合。
0xa1, 0x00, // COLLECTION (Physical)
//这是一个全局条目,选择用途页为按键(Button Page(0x09))
0x05, 0x09, // USAGE_PAGE (Button)
//这是一个局部条目,说明用途的最小值为1。实际上是鼠标左键。
0x19, 0x01, // USAGE_MINIMUM (Button 1)
//这是一个局部条目,说明用途的最大值为3。实际上是鼠标中键。
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
//这是一个全局条目,说明返回的数据的逻辑值(就是我们返回的数据域的值啦)
//最小为0。因为我们这里用Bit来表示一个数据域,因此最小为0,最大为1。
0x15, 0x00, // LOGICAL_MINIMUM (0)
//这是一个全局条目,说明逻辑值最大为1。
0x25, 0x01, // LOGICAL_MAXIMUM (1)
//这是一个全局条目,说明数据域的数量为三个。
0x95, 0x03, // REPORT_COUNT (3)
//这是一个全局条目,说明每个数据域的长度为1个bit。
0x75, 0x01, // REPORT_SIZE (1)
//这是一个主条目,说明有3个长度为1bit的数据域(数量和长度
//由前面的两个全局条目所定义)用来做为输入,
//属性为:Data,Var,Abs。Data表示这些数据可以变动,Var表示 //Var可以任意大小数据但是最小值要从0开始 Abs只能一个字节
//这些数据域是独立的,每个域表示一个意思。Abs表示绝对值。
//这样定义的结果就是,第一个数据域bit0表示按键1(左键)是否按下,
//第二个数据域bit1表示按键2(右键)是否按下,第三个数据域bit2表示
//按键3(中键)是否按下。
0x81, 0x02, // INPUT (Data,Var,Abs)
//这是一个全局条目,说明数据域数量为1个
0x95, 0x01, // REPORT_COUNT (1)
//这是一个全局条目,说明每个数据域的长度为5bit。
0x75, 0x05, // REPORT_SIZE (5)
//这是一个主条目,输入用,由前面两个全局条目可知,长度为5bit,
//数量为1个。它的属性为常量(即返回的数据一直是0)。
//这个只是为了凑齐一个字节(前面用了3个bit)而填充的一些数据
//而已,所以它是没有实际用途的。
0x81, 0x03, // INPUT (Cnst,Var,Abs)
//这是一个全局条目,选择用途页为普通桌面Generic Desktop Page(0x01)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
//这是一个局部条目,说明用途为X轴
0x09, 0x30, // USAGE (X)
//下面两个为全局条目,说明返回的逻辑最小和最大值。 屏幕大小 1920*1080
//这里定义X的逻辑最小值为0,即坐标原点
//X的逻辑最大值为1919,即屏幕x的坐标为(0,1919)。
//由于1920超过了一字节的范围,所以需要用2字节的格式表示最大值
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x7f, 0x07, // LOGICAL_MAXIMUM (1919)
//下面两个为全局条目,说明返回的物理最小和最大值。
//这里定义X的物理最小值为0,即坐标原点
//X的物理最大值为1919,即屏幕x的坐标为(0,1919)。
//由于1920超过了一字节的范围,所以需要用2字节的格式表示最大值
0x35, 0x00, //Physical Minimum (0)
0x46, 0x7f, 0x07, //Physical Maximum(1919)
//这是一个全局条目,说明数据域的长度为16bit。
0x75, 0x10, // REPORT_SIZE (16)
//这是一个全局条目,说明数据域的个数为1个。
0x95, 0x01, // REPORT_COUNT (1)
//这是一个主条目。它说明这两个16bit的数据域是输入用的,
//属性为:Data,Var,Abs。Data说明数据是可以变的,Var说明
//这些数据域是独立的,Abs表示这些值是绝对值。
0x81, 0x02, // INPUT (Data,Var,Abs)
//这是一个局部条目,说明用途为Y轴
0x09, 0x31, // USAGE (Y)
//下面两个为全局条目,说明返回的逻辑最小和最大值。
//这里定义Y的逻辑最小值为0,即坐标原点
//Y的逻辑最大值为1079,即屏幕Y的坐标为(0,1079)。
//由于1080超过了一字节的范围,所以需要用2字节的格式表示最大值
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x37, 0x04, // LOGICAL_MAXIMUM (1079)
//下面两个为全局条目,说明返回的物理最小和最大值。
//这里定义Y的物理最小值为0,即坐标原点
//Y的物理最大值为1079,即屏幕Y的坐标为(0,1079)。
//由于1080超过了一字节的范围,所以需要用2字节的格式表示最大值
0x35, 0x00, //Physical Minimum (0)
0x46, 0x37, 0x04, //Physical Maximum(1079)
//这是一个全局条目,说明数据域的长度为16bit。
0x75, 0x10, // REPORT_SIZE (16)
//这是一个全局条目,说明数据域的个数为1个。
0x95, 0x01, // REPORT_COUNT (1)
//这是一个主条目。它说明这两个16bit的数据域是输入用的,
//属性为:Data,Var,Abs。Data说明数据是可以变的,Var说明
//这些数据域是独立的,Abs表示这些值是绝对值。
0x81, 0x02, // INPUT (Data,Var,Abs)
//下面这两个主条目用来关闭前面的集合用。
//我们开了两个集合,所以要关两次。bSize为0,所以后面没数据。
0xc0, // END_COLLECTION
0xc0 , // END_COLLECTION
触模设备描述符
手机使用,模拟的是触摸动作,个人测试实际使用中ios上无响应,安卓通过,不清楚是参数的原因或是其它,建议优先测试安卓:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
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,
0x15 , 0x00 ,
0x25 , 0x01 ,
0x81 , 0x02 ,
0x09 , 0x51 ,
0x75 , 0x05,
0x95 , 0x01 ,
0x16 , 0x00 , 0x00,
0x26 , 0x10 , 0x00,
0x81 , 0x02,
0x09 , 0x47 ,
0x75 , 0x01,
0x95 , 0x01 ,
0x15 , 0x00,
0x25 , 0x01 ,
0x81 , 0x02 ,
0x05 , 0x01 ,
0x09 , 0x30 ,
0x75 , 0x10 ,
0x95 , 0x01 ,
0x55 , 0x0D,
0x65 , 0x33,
0x35 , 0x00,
0x46 , 0x37, 0x04 , //逻辑分辨率 1079
0x26 , 0x37, 0x04 , //物理分辨率
0x81 , 0x02 ,
0x09 , 0x31 ,
0x75 , 0x10 ,
0x95 , 0x01 ,
0x55 , 0x0D ,
0x65 , 0x33 ,
0x35 , 0x00 ,
0x46 , 0x5f, 0x09, //逻辑分辨率2399
0x26 , 0x5f, 0x09 , //物理分辨率
0x81 , 0x02 ,
0x05 , 0x0D ,
0x09 , 0x55 ,
0x25 , 0x08 ,
0x75 , 0x08 ,
0x95 , 0x01 ,
0xB1 , 0x02 ,
0xC0 ,
0xC0 ,
};
二,usbd_hid.h
绝对位置鼠标:
#define HID_EPIN_SIZE 0x06U
#define HID_MOUSE_REPORT_DESC_SIZE 74U //默认就这个,不变触控设备:
#define HID_EPIN_SIZE 0x05U
#define HID_MOUSE_REPORT_DESC_SIZE 112U //需要修改为112U红米6pro上的测试
尝试将描述符里的宽高都定义为了4096:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
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,
0x25, 0x01,
0x81, 0x02,
0x09, 0x51, // USAGE (Contact Identifier)
0x75, 0x05,
0x95, 0x01,
0x16, 0x00, 0x00,
0x26, 0x10, 0x00,
0x81, 0x02,
0x09, 0x47, // USAGE (Confidence)
0x75, 0x01,
0x95, 0x01,
0x15, 0x00,
0x25, 0x01,
0x81, 0x02,
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 (EnglishLinear, cm)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x00, 0x10, // PHYSICAL_MAXIMUM (4096)
0x26, 0x00, 0x10, // LOGICAL_MAXIMUM (4096)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x75, 0x10,
0x95, 0x01,
0x55, 0x0D,
0x65, 0x33,
0x35, 0x00,
0x46, 0x00, 0x10, // PHYSICAL_MAXIMUM (4096)
0x26, 0x00, 0x10, // LOGICAL_MAXIMUM (4096)
0x81, 0x02,
0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x55, // USAGE (Contact Count)
0x25, 0x08, // LOGICAL_MAXIMUM (8)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0xb1, 0x02, // FEATURE (Data,Var,Abs)
0xc0,
0xc0,
};测试用的程序:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
#include "usbd_hid.h"
/* Private variables ---------------------------------------------------------*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* Private define ------------------------------------------------------------*/
// 触摸屏描述符定义的最大坐标 (4096 x 4096)
#define TOUCH_MAX 4095
// 红米6 Pro 屏幕比例 19:9,使用通用4096坐标系
// 系统会自动缩放适配 1080 x 2280 的物理分辨率
// 5个测试点坐标 (使用比例值,便于适配各种屏幕)
// 屏幕四个方向留出约1/16的边距,避开圆角区域
#define X_LEFT 256 // 左侧边距 (4096/16 = 256)
#define X_RIGHT 3840 // 右侧边距 (4096 - 256)
#define Y_TOP 256 // 顶部边距
#define Y_BOTTOM 3840 // 底部边距
// 中心点
#define X_CENTER 2048 // 屏幕中心
#define Y_CENTER 2048
// 红米6 Pro 专用测试点 (如果你想精确点击特定位置)
// 物理分辨率 1080x2280 映射到 4096 坐标的公式: coord = (physical * 4096) / resolution
// 例如:竖屏模式下,X轴 1080 映射到 4096,Y轴 2280 映射到 4096
#define PHYSICAL_WIDTH 1080
#define PHYSICAL_HEIGHT 2280
// 将物理坐标转换为4096坐标的宏
#define PHYSICAL_TO_TOUCH(physical, max) ((uint16_t)(((uint32_t)physical * 4096) / max))
// 预定义一些常用位置 (竖屏模式)
// 左上角区域 (避开圆角)
#define POS_TOP_LEFT_X PHYSICAL_TO_TOUCH(100, PHYSICAL_WIDTH) // 约 379
#define POS_TOP_LEFT_Y PHYSICAL_TO_TOUCH(150, PHYSICAL_HEIGHT) // 约 269
// 右上角区域
#define POS_TOP_RIGHT_X PHYSICAL_TO_TOUCH(980, PHYSICAL_WIDTH) // 约 3717
#define POS_TOP_RIGHT_Y PHYSICAL_TO_TOUCH(150, PHYSICAL_HEIGHT) // 约 269
// 左下角区域
#define POS_BOTTOM_LEFT_X PHYSICAL_TO_TOUCH(100, PHYSICAL_WIDTH) // 约 379
#define POS_BOTTOM_LEFT_Y PHYSICAL_TO_TOUCH(2130, PHYSICAL_HEIGHT) // 约 3826
// 右下角区域
#define POS_BOTTOM_RIGHT_X PHYSICAL_TO_TOUCH(980, PHYSICAL_WIDTH) // 约 3717
#define POS_BOTTOM_RIGHT_Y PHYSICAL_TO_TOUCH(2130, PHYSICAL_HEIGHT)// 约 3826
// 中心点
#define POS_CENTER_X PHYSICAL_TO_TOUCH(540, PHYSICAL_WIDTH) // 2048
#define POS_CENTER_Y PHYSICAL_TO_TOUCH(1140, PHYSICAL_HEIGHT) // 2048
// 触摸状态
#define TOUCH_PRESS 0x83 // 按下
#define TOUCH_RELEASE 0x82 // 松开
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void Error_Handler(void);
void Send_Touch(uint8_t state, uint16_t x, uint16_t y);
void Send_Touch_Physical(uint8_t state, uint16_t x_physical, uint16_t y_physical);
/* USER CODE BEGIN 0 */
/**
* @brief 发送触摸数据 (4096坐标系)
* @param state: 触摸状态 (0x83按下, 0x82松开)
* @param x: X坐标 (0-4095)
* @param y: Y坐标 (0-4095)
*/
void Send_Touch(uint8_t state, uint16_t x, uint16_t y)
{
uint8_t report[5];
// 限制坐标范围
if (x > TOUCH_MAX) x = TOUCH_MAX;
if (y > TOUCH_MAX) y = TOUCH_MAX;
report[0] = state; // 触摸状态
report[1] = (uint8_t)(x & 0xFF); // X低8位
report[2] = (uint8_t)((x >> 8) & 0xFF); // X高8位
report[3] = (uint8_t)(y & 0xFF); // Y低8位
report[4] = (uint8_t)((y >> 8) & 0xFF); // Y高8位
USBD_HID_SendReport(&hUsbDeviceFS, report, 5);
}
/**
* @brief 发送触摸数据 (物理坐标,自动转换)
* @param state: 触摸状态
* @param x_physical: X物理坐标 (0-1079)
* @param y_physical: Y物理坐标 (0-2279)
*/
void Send_Touch_Physical(uint8_t state, uint16_t x_physical, uint16_t y_physical)
{
uint16_t x_touch, y_touch;
// 物理坐标转换为4096坐标
x_touch = (uint32_t)x_physical * 4096 / PHYSICAL_WIDTH;
y_touch = (uint32_t)y_physical * 4096 / PHYSICAL_HEIGHT;
Send_Touch(state, x_touch, y_touch);
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
HAL_Delay(2000); // 等待USB稳定
// 测试方案1: 使用比例坐标 (适配各种屏幕)
// 测试点: 上中、右中、下中、左中、中心
while (1)
{
// 1. 上中 (靠近顶部)
Send_Touch(TOUCH_PRESS, X_CENTER, Y_TOP);
HAL_Delay(200);
Send_Touch(TOUCH_RELEASE, X_CENTER, Y_TOP);
HAL_Delay(500);
// 2. 右中 (靠近右侧)
Send_Touch(TOUCH_PRESS, X_RIGHT, Y_CENTER);
HAL_Delay(200);
Send_Touch(TOUCH_RELEASE, X_RIGHT, Y_CENTER);
HAL_Delay(500);
// 3. 下中 (靠近底部)
Send_Touch(TOUCH_PRESS, X_CENTER, Y_BOTTOM);
HAL_Delay(200);
Send_Touch(TOUCH_RELEASE, X_CENTER, Y_BOTTOM);
HAL_Delay(500);
// 4. 左中 (靠近左侧)
Send_Touch(TOUCH_PRESS, X_LEFT, Y_CENTER);
HAL_Delay(200);
Send_Touch(TOUCH_RELEASE, X_LEFT, Y_CENTER);
HAL_Delay(500);
// 5. 中心点
Send_Touch(TOUCH_PRESS, X_CENTER, Y_CENTER);
HAL_Delay(200);
Send_Touch(TOUCH_RELEASE, X_CENTER, Y_CENTER);
HAL_Delay(2000);
}
/* 如果想使用物理坐标测试,取消下面注释,并注释上面的while循环 */
/*
while (1)
{
// 1. 左上区域
Send_Touch_Physical(TOUCH_PRESS, 100, 150);
HAL_Delay(200);
Send_Touch_Physical(TOUCH_RELEASE, 100, 150);
HAL_Delay(500);
// 2. 右上区域
Send_Touch_Physical(TOUCH_PRESS, 980, 150);
HAL_Delay(200);
Send_Touch_Physical(TOUCH_RELEASE, 980, 150);
HAL_Delay(500);
// 3. 左下区域
Send_Touch_Physical(TOUCH_PRESS, 100, 2130);
HAL_Delay(200);
Send_Touch_Physical(TOUCH_RELEASE, 100, 2130);
HAL_Delay(500);
// 4. 右下区域
Send_Touch_Physical(TOUCH_PRESS, 980, 2130);
HAL_Delay(200);
Send_Touch_Physical(TOUCH_RELEASE, 980, 2130);
HAL_Delay(500);
// 5. 中心点
Send_Touch_Physical(TOUCH_PRESS, 540, 1140);
HAL_Delay(200);
Send_Touch_Physical(TOUCH_RELEASE, 540, 1140);
HAL_Delay(2000);
}
*/
/* USER CODE END 2 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
while(1)
{
}
}
因为触摸时是没有鼠标图标的,建议在开发者模式里开启触摸效果显示项。

