ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于STM32与MPU6050的低成本数据手套DIY:从硬件到Unity的完整实现

基于STM32与MPU6050的低成本数据手套DIY:从硬件到Unity的完整实现 简介这是一套面向嵌入式开发与虚拟现实交互初学者的完整项目实践资源聚焦基于STM32的姿态感知与无线人机交互系统设计。资源解决了传统游戏外设交互僵硬、VR手势识别成本高、软硬件协同调试困难等实际问题适用于课程设计、毕业设计及Unity3D体感应用原型开发。压缩包共136个文件含17个核心头文件h、14个C源码c、15个编译中间文件o、4个PDF设计文档、2个可执行程序exe、1个Android安装包apk及1个Keil工程文件uvproj涵盖STM32底层驱动、MPU6050姿态解算、蓝牙通信协议栈、Qt手机端UI与Unity3D双向数据桥接逻辑总大小69.14MB。已有393人学习下载提供从硬件电路设计含SchDoc原理图、固件烧录hex/axf、APP部署apk到Unity集成的全链路实现配套设计文档与B站实操视频进一步降低理解门槛。1. 项目缘起从“隔空操作”到“指尖触感”的探索几年前我在一个游戏开发者聚会上看到有人用昂贵的商业动捕手套演示VR射击游戏手指的每一次弯曲、手腕的每一次转动都能在虚拟世界里精准复现。那种沉浸感让我印象深刻但一问价格动辄数万瞬间劝退。当时我就想能不能用我们手头最常见的微控制器比如STM32自己搓一个能玩的数据手套成本控制在几百块精度和延迟也能满足普通游戏和创意交互的需求。这个想法一直搁在心里直到最近手头一个项目结束终于有时间把它从“想法”变成“实物”。我手头正好有一块STM32F103C8T6也就是常说的“蓝莓派”或“最小系统板”一些弯曲传感器、MPU6050姿态传感器还有几块废旧手套的布料。我的目标很明确做一只能捕捉五指弯曲和手腕旋转姿态的数据手套通过无线方式比如蓝牙将数据实时发送到电脑在Unity或Unreal引擎里驱动一个虚拟手模型最终能用来玩一些支持自定义输入的游戏或者做一些简单的体感交互演示。网上相关的开源项目不少但要么只做了单点弯曲检测要么数据传输不稳定要么在PC端的数据解析和映射做得比较粗糙。我这个“序号143”的项目就是想在这些基础上把整个链路打通、做稳并且把过程中那些容易踩坑、资料又语焉不详的细节给补上。比如如何用STM32的ADC同时稳定采集多个弯曲传感器的值如何融合MPU6050的加速度计和陀螺仪数据得到稳定的手腕姿态角如何设计一个轻量且抗干扰的无线通信协议以及如何在游戏引擎里优雅地接收并解析这些数据驱动骨骼动画如果你也对用硬件捕捉动作、并应用到虚拟世界感兴趣无论你是嵌入式开发者、游戏爱好者还是创客这篇长文应该能给你提供一个从硬件焊接、固件编写到软件联调的完整实现路径。我会尽量把原理讲透把代码拆开把踩过的坑标红让你能跟着做出来甚至在此基础上玩出更多花样。2. 核心器件选型与电路设计思路做数据手套第一步是确定要捕捉哪些数据以及用什么传感器来捕捉。我的设计目标是捕捉五指弯曲和手腕的旋转姿态。前者对应游戏里的抓握、开枪、手势识别等动作后者则对应挥剑、转向等动作。2.1 传感器选型为什么是它们1. 手指弯曲传感器模拟弯曲传感器 vs. 柔性弯曲传感器常见的弯曲传感器主要有两种一种是电阻式模拟弯曲传感器外形像一条塑料片弯曲时电阻值线性变化另一种是更先进的柔性弯曲传感器可以像布一样缝在手套上。前者单价在20-50元后者则要贵上数倍。对于原型验证和成本控制我选择了5条10kΩ的模拟弯曲传感器。它的优点是价格低廉、接口简单只需要一个ADC引脚和一个上拉/下拉电阻缺点是存在机械疲劳寿命且弯曲响应不是完全的线性需要后期校准。在实际购买时要注意选择长度适合手指的型号我用的约5cm。2. 姿态传感器MPU6050的“性价比之王”地位手腕姿态需要获取三维空间中的角度。虽然MPU9250集成磁力计或更高级的BMI160等传感器也能用但MPU6050集成3轴陀螺仪3轴加速度计以其极高的性价比、丰富的资料和稳定的性能依然是入门和中级项目的首选。它通过I2C接口与STM32通信可以输出原始的角速度和加速度数据。获取稳定姿态角的关键在于传感器融合算法MPU6050自带的DMP数字运动处理器单元可以帮我们完成这一步极大减轻MCU的负担。这也是选它的一个重要理由。3. 主控为什么是STM32F103C8T6“蓝莓派”核心板几乎是STM32爱好者的标配。72MHz主频、64KB Flash、20KB RAM性能对于处理5路ADC采样、运行I2C读取MPU6050、进行初步的数据滤波和打包并通过串口发送数据来说绰绰有余。更重要的是其丰富的外设多路ADC、多个定时器、USART等为我们的设计提供了硬件基础。而且社区资源极其丰富遇到问题基本都能找到解决方案。4. 无线模块HC-05蓝牙模块的务实之选为了摆脱线缆的束缚无线传输是必须的。WiFi如ESP8266功耗和复杂度较高2.4G私有协议如NRF24L01需要额外的接收器。而HC-05蓝牙模块是一个折中且成熟的选择。它成本低约20元通过串口AT指令配置可以与电脑或手机直接配对实现虚拟串口通信。虽然理论带宽和实时性不如专用协议但对于传输几十个字节的手套数据帧每秒50-100帧来说完全足够。它的缺点是连接稳定性偶尔会受环境干扰需要在软件层面做一些容错处理。2.2 电路连接与供电设计整个系统的供电是关键。传感器和MCU需要稳定的3.3V电压。如果使用USB供电比如从电脑或充电宝取电可以直接使用STM32开发板上的3.3V稳压输出。但如果想做成真正可穿戴的就需要考虑电池供电。我选择了一款常见的3.7V 500mAh锂电池配合一个微型TP4056充电保护一体板再连接一个AMS1117-3.3稳压模块为整个系统供电。这样手套可以充电续航根据数据发送频率能达到几个小时。具体接线如下这是一个原理性连接具体引脚需根据你的板子调整STM32F103C8T6核心板PA0-PA4分别连接5根弯曲传感器的信号线中间引脚。每根传感器另一端接10kΩ下拉电阻到GND信号线同时连接到STM32的ADC引脚。这样传感器弯曲电阻减小ADC读取的电压值降低。PB6 (I2C1_SCL),PB7 (I2C1_SDA)连接MPU6050的SCL和SDA同时接4.7kΩ上拉电阻到3.3V。PA9 (USART1_TX),PA10 (USART1_RX)连接HC-05蓝牙模块的RXD和TXD。注意MCU的TX接蓝牙模块的RXMCU的RX接蓝牙模块的TX。3.3VGND为所有传感器和模块供电。MPU6050模块VCC - 3.3V,GND - GNDAD0接地设置I2C地址为0x68。如果接3.3V地址则为0x69。HC-05蓝牙模块VCC - 5V(注意很多HC-05模块需要5V供电才能正常工作虽然IO口是3.3V电平。请务必查阅你的模块资料。如果模块支持3.3V则接3.3V更省电)。GND - GNDSTATE可接一个LED用于指示连接状态可选。注意1电平匹配STM32是3.3V逻辑电平HC-05如果是5V供电其TX引脚输出可能是5V电平直接接STM32的RX3.3V耐受有风险。稳妥做法是在HC-05的TX和STM32的RX之间加一个电平转换电路如分压电阻或电平转换芯片。我实测中很多HC-05模块在5V供电时TX输出也是3.3V左右但为了保险建议加上转换或选择声称兼容3.3V的模块。注意2电源去耦在每个主要芯片STM32、MPU6050的电源引脚附近尽量接一个0.1uF的陶瓷电容到地用于滤除高频噪声这对ADC采样和I2C通信的稳定性非常重要。注意3传感器固定弯曲传感器需要用柔软的方式固定在手套手指部位。我使用了一种柔性硅胶胶带既能粘牢又不会过度限制传感器弯曲。切忌用硬质胶水完全糊死会影响传感器寿命和弯曲线性度。3. 固件开发STM32上的数据采集与融合硬件连好后大脑在STM32里。我们使用STM32CubeIDE进行开发利用HAL库加快进度。整个固件的逻辑可以分解为几个并行的任务但考虑到F103没有操作系统我们用中断主循环的方式来实现。3.1 系统初始化与外设配置首先用CubeMX初始化项目配置时钟树使用外部8MHz晶振倍频到72MHz然后关键外设配置如下ADC配置用于弯曲传感器启用ADC1设置PA0-PA4为5个ADC通道。工作模式选择“扫描模式”和“连续转换模式”。这样ADC会自动按顺序循环扫描这5个通道。使用DMA传输。这是稳定采集多通道ADC的关键为ADC1配置一个DMA通道模式为“循环模式”数据宽度为半字16位。这样ADC每转换完一个通道的数据就会通过DMA自动存放到我们指定的数组中完全不需要CPU干预效率极高且定时准确。采样时间设置为239.5个周期提供足够的采样精度。在代码中我们定义一个数组uint16_t adc_values[5];并在初始化后启动ADC的DMA传输HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_values, 5);。之后adc_values数组里就会自动更新着5个通道的最新ADC值。I2C配置用于MPU6050启用I2C1速度模式选择“标准模式”100kHz或“快速模式”400kHz均可。我选择400kHz以获得更快的读取速度。注意上拉电阻必须接好否则通信可能失败。USART配置用于蓝牙通信启用USART1波特率设置为115200这是HC-05的常见默认波特率也可通过AT指令修改。启用USART的全局中断以便在收到PC端可能的配置指令时能及时响应虽然本项目主要单向发送但保留接收能力是好习惯。定时器配置用于控制发送频率启用一个基本定时器如TIM2将其配置为产生固定频率的中断例如100Hz即10ms一次。在定时器中断服务函数中设置一个标志位主循环检测到这个标志位就执行一次“读取传感器-处理数据-打包发送”的流程。这样我们就有了一个稳定的数据发送节拍。3.2 MPU6050的驱动与姿态解算这是固件的核心难点之一。我们不仅要读出原始数据还要得到稳定的俯仰角Pitch和横滚角Roll。偏航角Yaw需要磁力计MPU6050无法单独提供但对于手腕旋转Pitch和Roll已经足够。步骤1初始化与DMP加载MPU6050的初始化顺序很重要。网上有开源的MPU6050_6Axis_MotionApps20.h等库文件它封装了DMP的初始化和使用。大致流程是复位设备。唤醒设备退出睡眠模式。设置陀螺仪和加速度计的量程例如陀螺仪±2000°/s加速度计±2g。配置DMP功能并加载固件库一个很长的数组到MPU6050的芯片内。设置DMP输出速率例如100Hz。使能DMP并等待其准备就绪。这些步骤在开源库中都有现成函数我们主要调用即可。关键在于必须确保I2C通信绝对稳定。我在初始化函数里加入了重试机制如果某一步失败比如读取WHO_AM_I寄存器返回值不是0x68会延迟后重试几次并在调试串口打印信息这对排查硬件连接问题非常有帮助。步骤2读取四元数与欧拉角DMP准备好后它会以设定的频率产生中断MPU6050的INT引脚接到STM32的外部中断引脚或者我们可以通过轮询方式检查FIFO先进先出缓冲区是否有数据。 当有新的姿态数据时DMP输出的是四元数q0, q1, q2, q3。我们需要将其转换为更直观的欧拉角。库函数通常提供了dmpGetQuaternion()和dmpGetEuler()函数来完成这个转换。 最终我们得到以弧度表示的俯仰角pitch、横滚角roll和偏航角yaw。对于手腕我们主要关心pitch手腕上下摆动和roll手腕左右翻转。踩坑记录DMP初始化失败与校准DMP加载失败最常见的原因是I2C通信受到干扰。除了检查硬件上拉电阻和走线可以尝试降低I2C速度到100kHz。另外确保给MPU6050供电的3.3V电源足够干净加去耦电容。姿态角漂移即使使用了DMP传感器在静止时角度也可能缓慢漂移这是低成本MEMS传感器的通病。解决方法是上电后执行一次静态校准将手套平放在静止的桌面上几秒钟在这段时间内连续读取加速度计数据计算平均值这个平均值就是“水平静止”状态下的加速度参考值理论上应该是[0, 0, 1g]。在后续解算中用原始数据减去这个零偏可以显著改善静态精度。DMP本身也有自校准功能但手动校准效果更直接。3.3 数据滤波、打包与发送1. ADC数据的滤波处理从DMA直接读出的adc_values是原始值范围0-409512位ADC。它包含噪声且与手指弯曲角度并非完全线性。处理流程如下软件滤波对每个通道的数据进行滑动平均滤波或一阶低通滤波。例如filtered_value 0.9 * filtered_value 0.1 * new_adc_value。这能有效平滑数据避免抖动。标定与映射我们需要建立ADC值与物理弯曲角度的关系。让手指完全伸直记录每个传感器的ADC值max_val让手指完全握拳记录ADC值min_val。然后将实时滤波后的值映射到0-100的范围或0.0-1.0的归一化值angle_percent (filtered_val - min_val) * 100 / (max_val - min_val)。注意因为传感器特性可能需要分段线性映射或查表法来获得更好的线性度。2. 数据打包协议设计为了高效、可靠地通过蓝牙串口发送我们需要设计一个简单的帧协议。一个经典的格式是帧头 数据 校验和 帧尾。 例如[0xAA, 0x55, pitch_H, pitch_L, roll_H, roll_L, thumb, index, middle, ring, pinky, checksum, 0x0D, 0x0A]0xAA, 0x55固定的帧头用于在接收端识别一帧数据的开始。pitch, roll将浮点数姿态角乘以100转为整数保留两位小数然后拆分为高8位和低8位发送。thumb...pinky5个手指的弯曲百分比0-100用一个字节表示。checksum校验和可以是前面所有数据字节的简单累加和取低8位用于检测传输错误。0x0D, 0x0A\r\n帧尾方便在串口助手中直观查看。在STM32端我们在定时器触发的主循环任务中完成一次所有数据的采集、滤波、转换、打包然后调用HAL_UART_Transmit(huart1, data_packet, packet_length, 100);将数据包通过串口1连接蓝牙模块发送出去。注意发送间隔与数据量定时器中断设为100Hz但并不意味着每10ms就一定要发一包。可以根据需要调整比如50Hz20ms一包对于很多应用已经足够流畅并能降低功耗和无线干扰。一包数据大约15字节在115200波特率下发送一包数据不到2ms完全来得及。4. 上位机软件从字节流到虚拟手驱动手套的数据通过蓝牙传到电脑会变成一个虚拟串口例如COM5。上位机软件的任务就是打开这个串口按照我们定义的协议解析数据并将解析出的手指弯曲度和手腕姿态角映射到3D软件如Unity中的虚拟手模型上。4.1 串口通信与数据解析我选择用Python快速开发上位机原型因为它有丰富的串口pyserial和图形界面PyQt5或Tkinter库也方便与Unity等软件通信通过Socket或命名管道。import serial import struct class DataGloveReader: def __init__(self, portCOM5, baudrate115200): self.ser serial.Serial(port, baudrate, timeout1) self.buffer bytearray() self.packet_start False self.packet [] def find_and_parse_packet(self): while self.ser.in_waiting: byte self.ser.read(1)[0] self.buffer.append(byte) # 查找帧头 0xAA, 0x55 if len(self.buffer) 2 and self.buffer[-2] 0xAA and self.buffer[-1] 0x55: self.buffer self.buffer[-2:] # 找到帧头保留它们清空之前的不完整数据 self.packet_start True # 如果已经开始一帧并收集到足够的数据 if self.packet_start and len(self.buffer) PACKET_LENGTH: # 假设总包长15 # 验证帧尾和校验和 if self.buffer[-2] 0x0D and self.buffer[-1] 0x0A: checksum sum(self.buffer[2:-3]) 0xFF # 计算校验和不包括帧头、校验和字节本身、帧尾 if checksum self.buffer[-3]: # 校验和字节 # 解析数据 pitch_int (self.buffer[2] 8) | self.buffer[3] roll_int (self.buffer[4] 8) | self.buffer[5] pitch pitch_int / 100.0 # 恢复为浮点数 roll roll_int / 100.0 fingers list(self.buffer[6:11]) # 5个手指的数据 self.buffer.clear() self.packet_start False return {pitch: pitch, roll: roll, fingers: fingers} # 如果验证失败清空缓冲区重新寻找帧头 self.buffer.clear() self.packet_start False return None这个类会持续读取串口数据按照协议切分出完整的数据包并返回一个包含解析后数据的字典。4.2 数据平滑与映射从串口解析出的数据可能仍有微小抖动。在上位机可以再进行一次滤波比如使用指数平滑滤波smoothed_value alpha * new_value (1 - alpha) * smoothed_value其中alpha是一个介于0和1之间的平滑因子值越小越平滑但延迟越大。接下来是关键一步将物理数据映射到虚拟手骨骼。不同的3D软件和模型骨骼命名、旋转轴向可能不同。以Unity为例一个常见的人手模型会有大约15块骨骼每根手指3节。手指映射将拇指、食指、中指、无名指、小指的弯曲百分比0-100映射到对应手指的近端指骨和中间指骨的X轴或Z轴旋转上。通常不是简单的线性映射需要根据模型调整曲线。例如弯曲度50%可能对应指骨旋转45度。小指和无名指可能还需要一点联动。手腕映射将pitch和roll角度映射到手腕骨骼的局部旋转上。注意坐标系的转换手套传感器的坐标系与Unity世界坐标系或模型局部坐标系可能不一致可能需要交换轴或取反。这需要反复调试。4.3 Unity中的集成在Unity中我们可以创建一个脚本通过.NET的SerialPort类直接读取串口但更推荐用Python等中间件因为串口阻塞可能影响Unity主线程或者通过本地SocketUDP与Python上位机通信。Python程序解析并处理好数据后通过UDP发送给Unity这是更解耦、更稳定的方式。Unity脚本的核心是在Update()函数中接收来自Socket的数据包。解析出手腕的pitch,roll和五指弯曲度。将这些数值通过插值如Mathf.Lerp应用到对应的骨骼Transform的localRotation上。// 伪代码示例 public class GloveController : MonoBehaviour { public Transform wristBone; public Transform[] fingerBones; // 每根手指的骨骼数组 private float receivedPitch, receivedRoll; private float[] receivedFingerBends new float[5]; void Update() { // 假设从网络线程安全地获取了最新数据 receivedPitch, receivedRoll, receivedFingerBends // 应用手腕旋转 (注意轴顺序和方向可能需要调整) wristBone.localRotation Quaternion.Euler(receivedPitch, 0, receivedRoll); // 应用手指弯曲 for(int i0; i5; i){ float bendAngle MapPercentToAngle(receivedFingerBends[i]); // 映射函数 // 通常需要驱动多节骨骼 fingerBones[i][0].localRotation Quaternion.Euler(bendAngle * 0.7f, 0, 0); // 近端指骨 fingerBones[i][1].localRotation Quaternion.Euler(bendAngle * 0.3f, 0, 0); // 中间指骨 } } }踩坑记录Unity中的手部动画模型骨骼问题不是所有手部模型都适合用代码直接驱动旋转。有些模型使用Humanoid Avatar系统更适合用Animator和动画状态机控制。对于这类模型我们可以将手套数据映射到Animator的参数上在动画控制器中制作Blend Tree来实现平滑的手指弯曲。旋转顺序与万向锁直接使用欧拉角设置旋转可能会遇到万向锁问题特别是在Pitch接近±90度时。更稳健的做法是在STM32端直接发送四元数q0-q3在Unity端使用Quaternion.Set来设置旋转可以避免这个问题。但这会增加数据传输量4个float vs 2个float。延迟与同步蓝牙传输、串口读取、网络通信、Unity渲染都会引入延迟。要确保整个管路的延迟在可接受范围内100ms。可以在数据包中加入时间戳在上位机进行简单的延迟补偿预测。5. 系统联调与性能优化实战所有部分单独测试通过后真正的挑战在于联调。问题往往出现在子系统之间的交互和边界条件下。5.1 稳定性测试与常见故障排查现象1数据断断续续时有时无。排查首先用串口助手直接连接STM32的USART1_TX引脚绕过蓝牙看原始数据是否稳定。如果稳定问题在蓝牙链路。蓝牙端解决检查HC-05模块供电是否充足5V供电时电流可能超过200mA尝试降低蓝牙串口波特率到9600或19200看是否改善。确保天线部分模块上的蛇形走线没有被金属或手完全遮挡。在代码中加入连接状态检测和断线重连机制。STM32端解决检查发送函数HAL_UART_Transmit的最后一个参数超时时间是否设置合理如果太短可能在忙时发送失败。确保在定时器中断中处理时间足够短不会错过下一次中断。现象2手指弯曲数据跳动大即使手静止也不稳。排查用万用表测量弯曲传感器信号端的电压看是否稳定。如果电压稳定问题在ADC或软件。硬件解决检查ADC参考电压是否稳定通常是3.3V在VREF引脚加滤波电容。确保传感器信号线远离MCU的晶振、数字开关信号等噪声源。软件解决增加软件滤波的强度如增大滑动平均窗口或降低一阶低通滤波的系数。检查ADC的DMA配置确保缓冲区大小匹配没有溢出。可以尝试在ADC采样期间短暂关闭其他高优先级中断。现象3手腕姿态角漂移严重或响应迟钝。排查读取MPU6050的原始加速度计和陀螺仪数据看是否在静止时接近理论值加速度计x0, y0, z1g陀螺仪xyz0。解决执行严格的传感器静态校准见3.2节。检查MPU6050是否安装牢固避免在手套弯曲时传感器本身发生不必要的移动。对于DMP输出可以适当降低输出速率如50Hz并在上位机做进一步互补滤波。5.2 功耗优化思路如果希望延长电池续航可以从以下几点优化降低发送频率将数据发送频率从100Hz降到30-50Hz对流畅度影响不大但功耗线性下降。STM32睡眠模式在数据采集发送的间隙让STM32进入SLEEP或STOP模式。可以通过定时器唤醒RTC或低功耗定时器。这需要精心设计程序架构确保外设如ADC、I2C在睡眠前后正确配置。传感器电源管理用STM32的GPIO控制一个MOSFET为MPU6050和弯曲传感器供电。只在需要采集的瞬间上电其他时间断电。但这会增加电路复杂度和响应延迟。蓝牙模块功耗HC-05在连接状态下功耗不低约30mA。可以调研更省电的蓝牙4.0BLE模块如HC-08但其数据传输方式和速率需要重新适配。5.3 扩展与进阶玩法基础功能实现后这个平台可以玩出很多花样手势识别在上位机或STM32端如果算法够简单实现一个手势识别引擎。连续采集多帧手指弯曲数据通过模板匹配或简单的机器学习如在PC端用Python的scikit-learn识别出“握拳”、“点赞”、“比耶”、“数字1-5”等手势并触发键盘鼠标事件或游戏内动作。力反馈在手套指尖或手心部位添加振动电机硬币马达。通过STM32的PWM驱动当在虚拟世界中触摸物体或开枪时让电机产生不同强度的振动增强沉浸感。这需要在上位机或游戏引擎中定义触发事件并通过串口反向发送控制指令给手套。多手套交互做两只手套实现双手交互。需要为两只手套设计不同的蓝牙地址或数据包ID上位机同时连接两个串口分别解析。集成到现有游戏使用像FreePIE或GlovePIE这样的输入模拟软件将手套数据映射为键盘按键、鼠标移动或游戏手柄信号从而兼容大量不支持直接外部设备输入的老游戏。更换主控如果觉得STM32F103性能或外设不够可以升级到STM32F4系列带浮点运算单元更适合做复杂滤波和融合算法或者使用集成了蓝牙的MCU如ESP32可以省去外部蓝牙模块进一步缩小体积。这个“序号143”的数据手套项目从构思到实现是一个典型的嵌入式系统开发流程需求分析、器件选型、硬件设计、固件开发、上位机软件、系统联调。每一步都有细节需要注意每一步也都有优化的空间。它不仅仅是一个玩具更是一个理解传感器、微控制器、实时数据处理和无线通信的绝佳平台。当你看到自己手指的每一次开合都能实时反映在屏幕中的虚拟手上时那种连接物理世界与数字世界的成就感是单纯购买成品无法比拟的。希望这篇详细的记录能帮你绕过我踩过的那些坑更快地享受到自己动手创造的乐趣。本文还有配套的精品资源点击获取
返回列表