十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Proteus仿真入门:51单片机循迹小车设计与算法实现

Proteus仿真入门:51单片机循迹小车设计与算法实现 简介本资源是一套面向单片机初学者与课程设计学生的简易自动循迹小车完整仿真开发包聚焦AT89C51最小系统下的红外循迹控制原理实践解决从传感器信号采集、PWM调速、转向逻辑判断到电机驱动的全流程闭环控制问题。压缩包共11个文件205KB含Proteus可运行仿真工程.pdsprj/.dsn、Keil C语言源程序.c、编译生成的HEX固件、工作空间配置及关键电路截图.png覆盖硬件建模、代码调试、仿真验证全环节。已有449人学习下载适合嵌入式入门者快速掌握循迹算法实现、Proteus与单片机协同仿真方法及典型光电检测电路设计。读者可直接加载仿真图观察红灯加热状态指示、调节PWM占空比验证速度响应并通过源码深入理解传感器信号判别逻辑与左右轮差速转向策略。1. 项目概述从零到一用仿真搞定你的第一辆循迹小车最近在整理资料翻到了当年带学生做课程设计时的一个经典项目——基于单片机的简易自动循迹小车。这个项目可以说是电子、自动化乃至机器人入门者的“必修课”它麻雀虽小五脏俱全涵盖了传感器应用、电机驱动、控制算法和系统集成等多个核心知识点。很多朋友一上来就想焊板子、调实物结果往往被硬件连接、电源干扰、电机抖动等问题搞得焦头烂额项目还没开始就结束了热情。我的建议是先仿真后实战。利用Proteus这样的电子设计自动化软件我们可以在电脑上搭建一个完整的虚拟硬件系统编写程序观察运行效果把所有逻辑和算法都调通。这就像建筑师先做3D效果图飞行员先在模拟器上训练一样能极大降低试错成本让你把精力集中在核心的“控制思想”上。今天我就以最经典的51单片机为核心带你一步步在Proteus里从零搭建一辆能自动沿着黑线跑的循迹小车并附上完整的仿真图和程序源码。无论你是正在备战电赛的学生还是对嵌入式感兴趣的爱好者这篇“仿真优先”的实践指南都能让你避开初期那些坑直击问题本质。2. 项目整体设计与核心思路拆解2.1 为什么选择“仿真先行”的策略在动手之前我们必须明确一个核心理念仿真是验证逻辑和算法的绝佳沙盒。对于循迹小车这个项目实物制作会引入大量不可控变量红外对管距离地面的高度稍有变化检测结果就天差地别L298N电机驱动板的接线松动会导致小车跑偏电池电压下降会影响电机转速和单片机稳定性。这些问题交织在一起会让调试变得异常痛苦你很难判断是程序逻辑错了还是硬件出了问题。而在Proteus仿真环境中这些硬件不确定性被极大消除了。传感器模型是理想的电机响应是即时的电源是稳定的。你的程序逻辑是否正确控制算法是否有效在这里可以得到最纯粹的检验。仿真的核心价值在于将“软件逻辑调试”与“硬件稳定性调试”这两个复杂问题解耦。我们先在理想环境下把软件做到100分再到现实世界中应对那80分的硬件挑战成功率会高得多。2.2 系统核心架构与模块划分一辆简易循迹小车的系统架构可以清晰地划分为感知、决策、执行三大模块。在Proteus中我们将用虚拟元件一一对应这些模块。感知模块眼睛负责“看”路。我们采用最经典、成本最低的方案——红外反射式光电传感器。通常使用3-5个并排安装在小车前端。其原理是红外发射管发出红外光照射到地面后反射由接收管接收。白色地面反射率高接收到的信号强黑色轨迹线反射率低接收到的信号弱。接收管的输出经过比较器或直接接入单片机IO口就能得到一个数字信号如白线为高电平1黑线为低电平0。在Proteus中我们可以用“红外对管”传感器模型来模拟或者更简单地直接用按-钮或开关来手动模拟不同循迹状态用于初步测试。决策模块大脑也就是我们的单片机这里是AT89C51。它不断读取感知模块传来的多个传感器状态根据一套预设的算法即“循迹策略”进行判断然后向执行模块发出相应的控制指令。这是整个项目的软件核心算法的好坏直接决定了小车跑得是“丝滑”还是“抽搐”。执行模块手脚负责将大脑的指令转化为动作。主要包括电机和驱动电路。我们通常使用两个直流减速电机分别驱动左右轮通过差速来实现转向。单片机IO口的电流太小无法直接驱动电机因此需要电机驱动芯片比如经典的L298N。在Proteus中我们有对应的L298模型可以完美模拟其驱动逻辑。电源模块心脏为所有模块供电。在仿真中我们直接使用直流电压源即可无需考虑纹波、压降等问题。整个系统的数据流是这样的传感器状态 - 单片机IO口输入 - 程序算法处理 - 单片机IO口输出 - L298N驱动芯片 - 左/右电机正转/反转/停止 - 小车运动。2.3 核心元器件选型与Proteus库对应在Proteus中搭建电路第一步是找到正确的元件模型。以下是本项目所需的核心元件及其在Proteus ISIS库中的搜索名称单片机CPUAT89C51或AT89C52。这是最经典的51内核单片机资源足够模型完善。电机驱动芯片L298。搜索后会出现L298N等模型注意它是一个模块内部包含了逻辑和驱动部分我们直接使用即可。直流电机MOTOR。在Proteus中搜索“MOTOR”或“DC MOTOR”可以找到直流电机模型。为了更直观地看到转向我们通常将电机连接到“车轮”模型上可以搜索MOTOR-ENCODER带编码器的电机但本项目未用编码器功能或直接用电机然后添加一个简单的可视化轮子。红外传感器对于纯数字逻辑仿真我们可以用BUTTON按钮来手动模拟传感器信号。如果想更贴近实物可以搜索INFRARED但Proteus自带的红外传感器模型可能交互性不强。一个更优的替代方案是使用ADC模型配合电压值来模拟传感器模拟量输出但为简化我们初期采用按钮模拟。基础元件晶振CRYSTAL通常选择12MHz。电容CAP普通电容用于电源滤波、CAP-ELEC电解电容用于复位电路。电阻RES。按键BUTTON用于复位和手动模拟传感器。电源/地POWER和GROUND。注意Proteus的电机模型在仿真运行时如果驱动电压和负载设置不当可能会出现转速异常甚至不转的情况。这恰恰是仿真有意义的体现——它提醒你即使在理想模型中电机的驱动逻辑使能、方向也必须完全正确。3. Proteus仿真电路图搭建详解3.1 单片机最小系统搭建任何单片机系统工作的基础都是最小系统。对于AT89C51这包括电源电路VCC GND在Proteus中直接从左侧工具栏选择“终端模式”找到POWER和GROUND分别放置。将POWER的电压属性设置为5V连接到单片机的第40脚VCC和第31脚EA/VPP接高电平表示使用内部程序存储器。所有GROUND连接到单片机的第20脚GND。时钟电路在12脚XTAL1和13脚XTAL2之间连接一个12MHz的CRYSTAL晶振。再从晶振的两端分别接一个22pF的CAP电容到地。这是为单片机提供工作节拍的心脏。复位电路在9脚RST上拉一个10kΩ的RES电阻到VCC同时通过一个10μF的CAP-ELEC电解电容接地。再并联一个BUTTON按键在电容两端。这样上电瞬间电容充电RST脚获得一个短暂的高电平脉冲实现上电复位按下按钮时直接将RST脚拉到VCC实现手动复位。3.2 传感器输入电路设计我们以经典的5传感器布局为例。将5个BUTTON按钮排成一行分别命名为S1最左、S2、S3中、S4、S5最右。每个按钮的一端接地GND另一端分别连接到单片机的一个IO口这里我们使用P1口S1-P1.0, S2-P1.1, S3-P1.2, S4-P1.3, S5-P1.4。这里有一个至关重要的细节必须在单片机的这些IO口P1.0-P1.4上各接一个上拉电阻例如10kΩ到VCC。为什么当按钮未按下模拟传感器检测到白线时我们希望IO口读到的是高电平1。如果什么都不接这个引脚处于“浮空”状态电平不确定极易受干扰。接上上拉电阻后就确保了按钮断开时引脚被稳定地拉到VCC。当按钮按下模拟传感器检测到黑线时引脚直接通过按钮连接到GND被拉成低电平0。这样我们就构建了5路数字输入1代表白线/未压线0代表黑线/压线。3.3 电机驱动电路连接L298N是一个双H桥驱动芯片可以驱动两个直流电机。在Proteus中放置L298模型它通常有多个引脚VCC逻辑电源接5V。VS电机驱动电源仿真中可以也接5V实物通常接更高电压如7-12V以获得更大扭矩。GND接地。IN1, IN2, ENA对应电机A我们设为左电机的控制端。IN3, IN4, ENB对应电机B我们设为右电机的控制端。连接逻辑如下左电机单片机P2.0 - L298 IN1 P2.1 - L298 IN2 P2.2 - L298 ENA。右电机单片机P2.3 - L298 IN3 P2.4 - L298 IN4 P2.5 - L298 ENB。控制真值表以左电机为例ENAIN1IN2电机状态110正转101反转111刹车停止100惯性停止0XX停止在程序中我们通常将ENA和ENB置为高电平1通过IN1/IN2和IN3/IN4来控制电机的正反转从而控制小车前进、后退、左转、右转和停止。最后将L298的OUT1, OUT2连接到左电机OUT3, OUT4连接到右电机。在Proteus中可以将电机另一端接地形成一个回路。3.4 一个完整的仿真图布局技巧将所有元件连接好后一个清晰的布局至关重要。建议将电路图分为几个功能区左上角单片机最小系统复位、晶振。正上方5个传感器按钮排成一行清晰标注。单片机右侧引出P1口和P2口的连线。右侧中部放置L298N驱动芯片并连接电机。电源和地使用总线模式或清晰的走线避免线路交叉混乱。务必使用“导线标签”功能为关键网络如P1.0,P2.0等命名这样在检查和后续分析时会非常方便。4. 循迹算法程序设计与代码实现电路是躯干程序才是灵魂。循迹算法的本质就是根据5个传感器输入的状态组合决定左右轮的速度差。4.1 基础控制逻辑差速转向小车的转向不是靠舵机而是通过差速实现的。即让左右两个轮子产生速度差。直行左右轮速度相等且同向。左转右轮速度 左轮速度甚至左轮停止或反转。右转左轮速度 右轮速度。 在数字控制中我们通常采用PWM脉冲宽度调制来调节电机速度。但为了最简化我们先实现最基础的“开关量”控制即电机只有“全速正转”、“全速反转”、“停止”三种状态。这足以让小车循迹只是动作会比较生硬。4.2 状态判断与决策表设计我们定义传感器状态0为检测到黑线压线1为检测到白底。那么5个传感器S1-S5会组成一个5位的二进制状态。根据小车相对黑线的位置我们可以定义几种典型状态并给出应对策略传感器状态 (S1 S2 S3 S4 S5)小车位置判断控制策略左轮 L 右轮 R0 1 1 1 1极端偏左仅最左传感器压线急左转L后退/停止 R全速前进1 0 1 1 1中度偏左左转L低速前进 R全速前进1 1 0 1 1基本居中中间传感器压线直行L全速前进 R全速前进1 1 1 0 1中度偏右右转L全速前进 R低速前进1 1 1 1 0极端偏右急右转L全速前进 R后退/停止0 0 0 0 0全部压线可能到终点或十字停止L停止 R停止1 1 1 1 1全部离线丢失轨迹原地缓慢旋转或按上次偏转方向搜索在实际编程中我们并不需要判断所有32种可能状态只需处理以上几种典型情况其余状态可以归类或做默认处理如继续上一状态。4.3 51单片机C语言程序框架以下是基于Keil C51开发环境的核心程序框架。程序采用“查询法”不断扫描传感器状态。#include REGX51.H // 包含AT89C51寄存器定义头文件 // 宏定义电机控制引脚 sbit MOTOR_L_IN1 P2^0; // 左电机方向1 sbit MOTOR_L_IN2 P2^1; // 左电机方向2 sbit MOTOR_L_ENA P2^2; // 左电机使能 sbit MOTOR_R_IN3 P2^3; // 右电机方向1 sbit MOTOR_R_IN4 P2^4; // 右电机方向2 sbit MOTOR_R_ENB P2^5; // 右电机使能 // 宏定义传感器引脚假设接在P1口低5位 #define SENSOR_PORT P1 // 函数声明 void Motor_Init(void); void Motor_Control(unsigned char left, unsigned char right); void Delay_ms(unsigned int t); void main(void) { unsigned char sensor_value; Motor_Init(); // 初始化电机控制引脚 while(1) { sensor_value SENSOR_PORT 0x1F; // 读取P1口低5位即5个传感器状态 // 根据sensor_value调用不同的电机控制函数 switch(sensor_value) { case 0x1E: // 二进制 11110 即 0 1 1 1 1 (极端偏左) Motor_Control(0, 1); // 左轮停/反转右轮正转 break; case 0x1D: // 11101 即 1 0 1 1 1 Motor_Control(1, 2); // 左轮慢速右轮全速 (需要PWM实现此处用1表示慢速模式) break; case 0x1B: // 11011 即 1 1 0 1 1 (居中) Motor_Control(1, 1); // 双轮全速正转 break; case 0x17: // 10111 即 1 1 1 0 1 Motor_Control(2, 1); // 左轮全速右轮慢速 break; case 0x0F: // 01111 即 1 1 1 1 0 (极端偏右) Motor_Control(1, 0); // 左轮正转右轮停/反转 break; case 0x00: // 00000 全部压线 Motor_Control(0, 0); // 停止 break; case 0x1F: // 11111 全部离线 // 可以加入搜索算法例如原地左转一小段时间 Motor_Control(0, 1); Delay_ms(100); break; default: // 其他未定义状态保持上一状态或停止 // Motor_Control(0,0); break; } Delay_ms(10); // 加入短暂延时防止程序跑飞也模拟控制周期 } } // 电机初始化所有控制引脚置低电机停止 void Motor_Init(void) { MOTOR_L_IN1 0; MOTOR_L_IN2 0; MOTOR_L_ENA 0; // 初始不使能 MOTOR_R_IN3 0; MOTOR_R_IN4 0; MOTOR_R_ENB 0; } // 简化版电机控制函数 // 参数: left/right: 0停止1前进2后退 (此版本仅为示意未实现PWM慢速) void Motor_Control(unsigned char left, unsigned char right) { MOTOR_L_ENA 1; // 使能电机 MOTOR_R_ENB 1; // 控制左电机 switch(left) { case 0: // 停止 MOTOR_L_IN1 0; MOTOR_L_IN2 0; break; case 1: // 前进 MOTOR_L_IN1 1; MOTOR_L_IN2 0; break; case 2: // 后退 MOTOR_L_IN1 0; MOTOR_L_IN2 1; break; } // 控制右电机 (逻辑同左) switch(right) { case 0: MOTOR_R_IN3 0; MOTOR_R_IN4 0; break; case 1: MOTOR_R_IN3 1; MOTOR_R_IN4 0; break; case 2: MOTOR_R_IN3 0; MOTOR_R_IN4 1; break; } } // 简易延时函数 void Delay_ms(unsigned int t) { unsigned int i, j; for(i0; it; i) for(j0; j120; j); }这个程序是一个最基础的框架。Motor_Control函数目前只实现了停止、全速前进、全速后退三种状态。要实现代码中提到的“慢速”就需要引入PWM。4.4 进阶加入PWM实现速度调节要让小车转弯更平滑必须能控制电机的速度。51单片机可以通过定时器中断生成PWM信号。例如我们使用定时器0设置一个固定的周期如1ms在中断服务程序中维护两个计数器分别对应左轮和右轮的“高电平时间”即占空比。// PWM相关全局变量 unsigned char PWM_Left_Duty 50; // 左轮占空比 0-100 unsigned char PWM_Right_Duty 50; // 右轮占空比 unsigned char PWM_Left_Counter 0; unsigned char PWM_Right_Counter 0; bit Motor_Left_Dir 1; // 方向1前进0后退 bit Motor_Right_Dir 1; void Timer0_Init(void) { TMOD 0xF0; // 设置定时器0模式116位定时器 TMOD | 0x01; TH0 (65536-1000)/256; // 1ms定时初值假设12MHz晶振 TL0 (65536-1000)%256; ET0 1; // 开启定时器0中断 EA 1; // 开启总中断 TR0 1; // 启动定时器0 } void Timer0_ISR(void) interrupt 1 { TH0 (65536-1000)/256; // 重装初值 TL0 (65536-1000)%256; PWM_Left_Counter; PWM_Right_Counter; if(PWM_Left_Counter 100) PWM_Left_Counter 0; // 周期100个单位 if(PWM_Right_Counter 100) PWM_Right_Counter 0; // 左电机PWM输出 if(PWM_Left_Counter PWM_Left_Duty) { // 在占空比时间内根据方向输出有效电平 if(Motor_Left_Dir) { MOTOR_L_IN1 1; MOTOR_L_IN2 0; } else { MOTOR_L_IN1 0; MOTOR_L_IN2 1; } } else { // 占空比之外的时间输出刹车或停止取决于驱动逻辑这里用停止 MOTOR_L_IN1 0; MOTOR_L_IN2 0; } // 右电机PWM输出逻辑同上 if(PWM_Right_Counter PWM_Right_Duty) { if(Motor_Right_Dir) { MOTOR_R_IN3 1; MOTOR_R_IN4 0; } else { MOTOR_R_IN3 0; MOTOR_R_IN4 1; } } else { MOTOR_R_IN3 0; MOTOR_R_IN4 0; } }这样在主程序的Motor_Control函数中我们就不再直接控制IN1/IN2的高低电平而是改为设置PWM_Left_Duty、PWM_Right_Duty和Motor_Left_Dir、Motor_Right_Dir这些全局变量。例如“左转”就可以设置为PWM_Left_Duty 30; PWM_Right_Duty 80;两个电机都正转但右轮更快从而实现平滑左转。5. Proteus仿真调试全流程与问题排查5.1 仿真运行步骤绘制电路图在Proteus ISIS中按照第三章节所述完整绘制电路图并检查连线。编译程序在Keil uVision中创建工程选择AT89C51为目标器件编写或粘贴上述C代码编译生成.HEX文件。加载程序回到Proteus双击原理图中的AT89C51单片机在弹出的属性对话框中在“Program File”一栏选择刚才Keil生成的.HEX文件。开始仿真点击Proteus界面左下角的运行按钮三角形。电路图上的电源指示灯如果有会亮起表示系统上电。交互测试在仿真运行时用鼠标点击我们之前放置的5个传感器按钮BUTTON模拟小车行驶过程中遇到的不同轨迹情况。观察两个电机的旋转方向是否符合预期电机上的箭头表示转向。5.2 常见仿真问题与解决方案即使是在仿真中也会遇到各种问题。以下是我在教学中学生最常遇到的几个坑问题1点击运行后单片机不工作电机毫无反应。排查首先检查单片机最小系统。确认晶振电路是否连接正确两个电容和晶振晶振频率是否设置双击晶振查看属性通常是12MHz。然后检查复位电路特别是上拉电阻和电解电容的极性是否正确。最后也是最关键的一步确认.HEX文件是否成功加载。双击单片机确保“Program File”路径正确。技巧可以在程序中初始化部分让一个特定的IO口如P0.0输出高电平并接一个LED。仿真运行时观察LED是否亮起这是判断程序是否开始运行的最简单方法。问题2电机只有一个转或者两个都不转但程序逻辑看起来没错。排查重点检查L298N的接线。确认ENA和ENB是否被程序置为高电平使能。检查IN1/IN2和IN3/IN4的电平组合是否符合控制真值表。在Proteus中你可以右键点击L298N的输入引脚选择“查看属性”或使用电压探针实时查看引脚电平。排查检查电机模型本身。Proteus中的直流电机模型有时需要设置机械负载。右键点击电机在属性中查看“Component Value”或“Load”如果负载设置过大即使驱动信号正确电机也可能转不动。可以先尝试设置为空或很小的值。问题3按下传感器按钮小车反应不对或者没反应。排查检查传感器输入电路的上拉电阻。如果没有上拉电阻按钮未按下时IO口是浮空的读取的状态随机。务必确保每个传感器输入引脚都通过一个电阻如10k连接到VCC。排查在程序中加入调试输出。例如将读取到的sensor_value实时输出到P0口并用Proteus的虚拟逻辑分析仪或简单的LED阵列来显示这个二进制值。这样就能直观地看到你按下按钮时单片机到底“读”到了什么。问题4小车动作“抽搐”不停地震动或转向过度。排查这通常是控制算法过于“敏感”或“迟钝”造成的。在仿真中由于没有物理惯性电机的启停是瞬间的。如果你的程序是“检测到偏左就立刻急左转下一秒检测到居中又立刻直行”就会导致抽搐。解决引入“状态保持”或“滞后区间”。例如定义一个“当前转向状态”变量。只有当传感器状态持续偏离中心若干毫秒后才改变转向指令。或者对于“中度偏左”这种状态不要给一个固定的“左转”指令而是根据偏离程度比如是S2压线还是S1压线来动态调整左右轮的PWM占空比差值实现比例控制这也就是PID算法的雏形。5.3 从仿真到实物的关键调整当仿真完美运行后准备制作实物时以下几点是必须调整的电源管理实物中必须使用稳压模块如7805为单片机和传感器提供稳定的5V电源。电机驱动电源L298N的VS最好单独供电如7.2V航模电池并与逻辑电源共地以避免电机启停对单片机造成干扰。传感器电路实物中需要使用真实的红外对管或红外循迹模块。这些模块通常输出的是模拟量或经过比较器后的数字量。你需要根据模块说明书调整电路和程序。传感器离地高度是关键通常需要反复调试1-3cm为宜并用螺丝固定。电机驱动L298N芯片或模块需要加装散热片。电机的两根线接到驱动板输出端时如果发现转向反了直接对调接线即可。程序优化仿真中的延时Delay_ms(10)在实物中可能需要调整。太快了CPU负担重且可能不稳定太慢了小车反应迟钝。需要实地测试。此外强烈建议在实物中加入“按键启动”、“蜂鸣器提示状态”、“LED指示”等功能方便调试。抗干扰在单片机的电源引脚附近通常是VCC和GND之间焊接一个0.1uF的瓷片电容和一个10uF的电解电容用于滤波。电机驱动电源输入端也建议并联大容量电解电容如100uF以上以吸收电流冲击。6. 项目扩展与进阶思路这个简易的循迹小车只是一个起点。在吃透基本原理后你可以从多个方向进行扩展让它变得更“聪明”算法升级从开关控制到PID。当前的算法是“bang-bang”控制非左即右转向生硬。可以尝试实现比例P控制转弯的幅度与偏离中心的程度成正比。更进一步加入积分I和微分D实现经典的PID控制算法让小车循迹如丝般顺滑。这在仿真中可以通过编写更复杂的算法来验证。传感器升级从数字到模拟。使用模拟输出的红外传感器或灰度传感器可以获取更丰富的路面信息不仅是黑或白还有不同程度的灰结合ADC模数转换读取能让小车提前感知弯道变化实现更精准的控制。功能扩展避障、遥控与测速。在车头加装超声波模块或红外避障模块实现循迹避障。增加蓝牙或红外接收模块实现手机APP或遥控器控制。在电机上加装编码器实现闭环速度控制让小车能以恒定速度行驶。控制器升级从51到STM32。51单片机资源有限处理复杂算法和多个外设时可能力不从心。可以尝试将主控换成STM32系列利用其更高的主频、更多的外设如高级定时器生成硬件PWM、多路ADC来构建性能更强的小车。在Proteus 8.9及以上版本中也支持部分STM32模型的仿真。仿真进阶自定义元件与动态测试。Proteus支持创建自定义元件模型。你可以尝试为更复杂的传感器或驱动模块创建仿真模型。此外可以利用Proteus的“激励源”和“图表”功能模拟一个动态变化的传感器信号输入自动测试你的控制程序在不同路径下的响应这比手动点击按钮要高效和全面得多。这个基于Proteus仿真的简易自动循迹小车项目就像一把钥匙为你打开了嵌入式系统和自动控制世界的大门。从看懂电路图到编写控制逻辑再到调试排错最后移植到实物每一步都充满了实践的乐趣和挑战。仿真阶段最大的收获是让你剥离了硬件的不确定性专注于逻辑和算法的锤炼。当你看到屏幕上的虚拟小车按照你编写的代码稳稳地沿着黑线前进、转弯时那种成就感是实实在在的。记住仿真是为了更好的实战调通仿真后大胆地去焊接你的第一块板子调试你的第一个实物小车吧那时你会发现之前仿真中思考的每一个细节都会在现实中得到回响。本文还有配套的精品资源点击获取
返回列表