尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

隔离区送餐机器人嵌入式设计:从系统架构到联调避坑全复盘

隔离区送餐机器人嵌入式设计:从系统架构到联调避坑全复盘 简介本资源是2022年全国大学生嵌入式芯片与系统设计竞赛参赛项目——基于龙芯教育派的隔离区自主送餐机器人完整源代码包面向嵌入式系统、机器人开发及国产处理器应用方向的高校学生与初阶开发者聚焦真实防疫场景下的自主导航、视觉识别与机电协同控制问题。压缩包含2003个文件主体为811个C源码含NCNN模型推理、RISC-V指令优化等核心模块、748个头文件支撑龙芯平台驱动与算法封装、400个Python脚本用于模型转换、数据预处理与通信调试辅以说明文档与配置脚本总大小207.83MB。已有154人学习下载代码结构体现典型嵌入式机器人分层架构涵盖感知SLAM/目标检测、决策路径规划、执行电机PID控制与通信Wi-Fi任务调度四大模块且大量使用onnx2ncnn、mat_pixel_rotate等轻量化AI部署组件适合作为国产化嵌入式AI落地的全流程学习范例。1. 从赛题到方案隔离区送餐机器人到底要解决什么问题2022年那届全国大学生嵌入式芯片与系统设计竞赛我们组拿到的任务是做一个隔离区自主送餐机器人平台锁定龙芯教育派也就是参赛编号0581那个项目。说实话刚看到题目的时候我心里其实是没底的。隔离区送餐看起来就是把餐从A点送到B点但真往细了想这个场景里全是嵌入式方向的经典问题上位机要跑界面、做决策下位机要控电机、采传感器中间还得有一套稳定可靠的通信机制。当时同赛道很多队伍做了智能小车、巡检机器人我们选送餐机器人核心原因只有一个这个场景离实际需求足够近。疫情背景下隔离病房、封闭管理区里医护人员的日常工作强度本来就高如果能让机器人替代人员完成一日三餐的定点配送不仅能降低交叉感染风险还能把人力资源释放到更关键的位置。1.1 隔离场景决定了机器人的硬性需求先把场景拆开看。隔离区的通道通常不算宽地面可能因为消毒作业残留水渍光线条件不稳定有时候还会临时摆放消毒设备、垃圾桶之类的障碍物。机器人要做的不是简单跑一圈而是从起始点出发依次经过多个隔离间门口停下、取餐、播报提示音、确认取走再前往下一个点最后回到起始点。这个流程里硬性需求其实被场景逼得很死自主路径规划不能靠遥控因为操作人员不能进入隔离区可靠的避障能力地面障碍物随时可能出现稳定的多点停靠精度送错房间是绝对不允许的低电量和故障状态下的提示至少不能无声无息地瘫在走廊里整个系统要能被非技术人员操作一键启动是最低要求。所以我们最终的作品并没有刻意堆叠很炫的技术而是把重点放在工程稳定性上。评审的时候评委问得最多的也是“如果这里出了故障你怎么处理”这说明竞赛考察的核心并不只是功能跑通而是整个系统的鲁棒性设计。1.2 竞赛规则视角下作品该做到什么程度嵌入式芯片与系统设计竞赛的评分逻辑每年都差不多首先是功能完整度其次才是创新性、文档和答辩表现。也就是说你做一个功能不完整的图像识别方案得分反而不如一个朴实但每一步都稳扎稳打的机械臂取餐方案。我们当时的策略很明确先把基础链路跑通再考虑加分项。基本链路是龙芯教育派上运行Qt程序作为调度中心通过串口下发指令给STM32底盘控制板底盘完成移动和停靠到了目标点之后教育派再通过串口控制舵机机械臂完成取餐动作。整套系统分为四个子系统各自独立最后通过协议对接。这个架构现在回头看很常规但在比赛现场恰恰是那些把基础链路做好、把异常情况考虑充分的队伍拿了高分。所以如果你准备参加类似的比赛我建议先问自己一个问题如果评委现场让你重复演示三次你的系统能每次都成功吗这个问题比任何花哨的功能都更致命。2. 龙芯教育派平台选型为什么选它它到底是一块什么板子既然题目锁定了龙芯教育派那这块板子就是我们整个系统的中枢。我先说说我对它的理解。龙芯教育派是龙芯中科面向教学场景推出的一款开发板板上主处理器来自龙芯2K系列指令集走的是龙芯自主的LoongArch。和常见的MCU开发板不同这块板子的定位更接近一个微型电脑能跑Linux系统有HDMI输出可以接显示器USB口能插键鼠也能编译运行Qt程序。板子上的UART、GPIO、I2C、SPI这些嵌入式接口也都引出来了方便做外围控制。对我们这种做机器人项目的队伍来说这块板子最大的价值在于它既能承担传统的嵌入式MCU控制任务又能胜任需要Linux环境的上层应用开发。比如我们项目里Qt界面、路径规划、串口协议都在板子上跑如果换一块普通STM32光是跑Qt就不现实。2.1 龙芯教育派的硬件底细因为比赛用的板子通常由组委会提供我这里只说我们实际用到的那部分资源。龙芯教育派的处理器主频在GHz级别内存也足够跑一个轻量级Linux桌面环境存储方面有eMMC或者SD卡可选对于送餐机器人这种应用场景存储完全够用。接口方面我们重点用了三类UART串口用来和STM32底盘通信这也是上下位机之间最主要的数据通道GPIO用来控制一些简单的数字信号比如蜂鸣器、状态指示灯USB和网络接口用来调试、传输数据后续如果要扩展摄像头做视觉识别也是走USB。需要特别说明的是龙芯教育派和树莓派这类板子在开发方式上有很大差异。树莓派普及度高网上资料多到看不完龙芯教育派更小众很多依赖库需要自己交叉编译适配。但换个角度看正因为生态不够成熟你对底层机制的理解反而会更深入。我们最初在板子上编译OpenCV链接一堆依赖库失败了好多次最后逐一手动编过这个过程的收获比跑通一个Demo大得多。2.2 开发环境搭建交叉编译与依赖库适配对不熟悉龙芯平台的选手来说开发环境这一步就容易卡一周。我们当时用的是x86主机上安装交叉编译工具链编译出LoongArch架构的可执行文件再传到板子上运行。交叉编译工具链的配置说简单也简单无非是下载合适的gcc设置环境变量、指定架构参数但坑在于很多第三方库没有现成的交叉编译包需要自己编译安装。一个典型的问题就是Qt。龙芯教育派厂商提供了适配好的Qt运行环境但如果你需要额外的模块比如串口通信的QSerialPort就可能需要自己补编译。这里我的经验是在configure阶段就指定好交叉编译前缀并且把依赖库的.pc文件路径配好否则后面qmake阶段会找不到库。export PATH/opt/loongarch64-toolchain/bin:$PATH export CCloongarch64-linux-gnu-gcc export CXXloongarch64-linux-gnu-g ./configure -prefix /opt/qt-loongarch -xplatform linux-loongarch-g make -j4 make install把Qt编好之后后面编其他库就顺畅多了。我的建议是把所有需要用的第三方库提前编好做成一个本地包管理目录避免现场演示前还在敲make命令。2.3 和树莓派方案相比差别在哪里很多同学会问为什么不用树莓派这个问题的答案首先是竞赛规则题目指定了龙芯教育派那硬件平台就不能变。从技术角度讲龙芯教育派的LoongArch指令集和x86、ARM都不一样生态和性能调优的路径也有差异。但从实际开发体验来看CPU性能对于我们这个项目来说已经绰绰有余。送餐机器人的核心计算量不在CPU而在电机控制、传感器数据的实时处理。这些任务我们放在了STM32上龙芯教育派主要做逻辑调度和界面展示两者各司其职比把全部任务堆在一块板子上更合理。所以我认为了解一块新平台的最好方式是拿它做一个完整的项目。当你在龙芯教育派上跑通了Qt界面、串口通信、路径规划你也就真正理解了嵌入式Linux开发的完整链路。3. 整体系统架构四个子系统怎么分工通信链路怎么设计整个送餐机器人的系统架构我在画第一版设计图时就没打算搞复杂。机器人不是越大而全越好而是每一层职责清晰、接口明确出了问题能快速定位。当时我们把它拆成了四个子系统子系统核心硬件主要职责移动底盘STM32、直流减速电机、编码器、电源模块电机控制、里程计采集、红外避障、PID闭环主控决策龙芯教育派任务调度、路径规划、串口通信、Qt界面显示取餐机构舵机、机械臂、限位开关餐柜门开合、取餐动作执行终端交互平板、WiFi模块任务下发、状态反馈四个子系统之间不是平级关系而是有明确的上下位机分层。龙芯教育派是大脑STM32是四肢机械臂是手平板是遥控器。下面我具体说说分层和通信是怎么设计的。3.1 上位机与下位机的职责划分很多人第一次做这种项目容易犯一个错误什么都想让上位机干。路径规划在Linux上算电机控制也在Linux上算串口直接连电机驱动板看起来简单实际调试起来很痛苦。Linux不是实时操作系统进程调度受系统负载影响如果Qt界面卡顿一下电机控制指令就延迟了机器人可能会冲出去。我们的做法是龙芯教育派只负责非实时任务比如界面响应、任务队列管理、路径规划计算所有实时性要求高的任务全部下沉到STM32。STM32做三件事——PID闭环控制、编码器读取、避障传感器采集。这些任务的时间要求都是毫秒级用裸机中断或者简单的时间片轮询就能稳定处理。上位机和下位机之间的数据流向非常清晰龙芯教育派发指令帧前进、后退、左转、右转、停止、取餐、关柜STM32回状态帧当前速度、编码器累计值、避障触发标志、低电量警告。这种分层有个好处以后你想把底盘换成其他控制板只用改下位机上位机协议不变或者你想把机械臂换成更复杂的结构也不用动底盘代码。模块之间的低耦合在比赛这种高压环境里特别有价值。3.2 串口通信协议设计一帧数据怎么定上下位机通信我们选择了串口原因很简单可靠、简单、在嵌入式开发里最常用。但没经验的人会忽略一个关键问题——串口是字节流没有天然的帧边界你得自己定义协议格式。我们最终定义的帧结构是这样typedef struct { uint8_t head; // 帧头 0xAA uint8_t cmd; // 命令字 uint8_t len; // 数据长度 uint8_t data[8]; // 数据区 uint8_t checksum; // 校验和 uint8_t tail; // 帧尾 0x55 } Frame;命令字设计如下命令字含义数据区说明0x01前进data[0]为速度档位0x02后退data[0]为速度档位0x03左转data[0]为角度0x04右转data[0]为角度0x05停止无0x10取餐data[0]为柜门号0x11关柜无校验方式用的是累加和简单可靠把所有字节累加后取低8位放在校验字段。为什么不用CRC因为串口通信距离短、干扰小累加和已经能覆盖绝大多数传输错误而且实现起来几行代码就能写完对MCU的算力要求更低。调试串口协议时一个重要技巧是先做离线回环测试。用一根USB转TTL线把板子的TX和RX短接往串口发数据再收回来看解析是否正常。这个步骤能帮你把协议本身的bug和硬件接线问题分开。3.3 软件线程模型与任务调度龙芯教育派上Qt程序的多线程设计也是一个小考点。如果直接在Qt主线程里调串口的waitForReadyRead界面一卡整个系统就跟着卡。我们的做法是单独开一个QThread里跑串口收发用信号槽机制和主线程通信。任务调度的核心是一个状态机。简单来说整个送餐流程可以用四个状态概括IDLE等待任务机器人原地待命NAVIGATE正在前往目标点底盘移动中DELIVER到达目标点执行取餐动作RETURN配送完成返回起始点。每个状态之间的跳转条件很明确。比如NAVIGATE状态下如果收到STM32回传的“已到位”状态帧就切换到DELIVERDELIVER执行完取餐、关柜后检查下一个目标点如果有就继续NAVIGATE没有就进入RETURN。用状态机的好处是逻辑不会乱任何时候你都知道系统处于什么阶段排查问题也方便。比赛答辩的时候把状态机画出来讲给评委听他们也更容易理解你的设计思路。4. 核心功能模块的代码实现与设计取舍这章可能是大家最关心的部分。送餐机器人看着功能不多但每个模块展开讲里面都有不少值得深挖的细节。4.1 移动底盘增量式PID与直行纠偏底盘是整个机器人最基础的执行单元跑得稳不稳直接影响送餐能不能成功。我们用的是两轮差速底盘两个直流减速电机带编码器后面加一个万向轮支撑。两轮差速底盘的转向实现很简单左轮和右轮速度不同车体就会转弯。但问题在于电机的转速和PWM占空比不是严格的线性关系电池电压变化、路面摩擦不同都会导致同样占空比下实际转速不一样。如果你直接开环控制机器人走不了多远就会偏。所以必须用PID闭环。我们采用的是增量式PID在STM32上以20ms为周期定时读取编码器计算实际速度和期望速度做差然后输出PWM修正值。int pid_update(PID_t *pid, int target, int current, float dt) { int err target - current; pid-integral err * dt; float derivative (err - pid-prev_err) / dt; float output pid-kp * err pid-ki * pid-integral pid-kd * derivative; pid-prev_err err; return (int)output; }调参是很多人头疼的事。我的经验是先调kp让系统在中等速度下不震荡再加kd抑制超调最后加一点ki消除稳态误差。每次只调一个参数从一组保守值开始逐步试探。还有一个细节很多人忽略直行纠偏不只要让每个轮子都达到目标转速还要让两个轮子的编码器累计值保持一致。如果一只轮子因为打滑多转了几圈光靠速度PID是看不出来的必须用里程计累计值做二次修正。我们在直行时每100ms对比一次左右编码器累计值误差超过一定阈值就微调一侧的目标速度。4.2 路径规划栅格地图上的A*搜索路径规划这个模块说实话我们一开始想得很复杂打算上SLAM建图。后来评估了一下工作量果断放弃了。竞赛场地通常是规则区域我们用栅格地图就足够了。做法是这样的把场地按10cm一个格子离散成一张二维地图障碍物和被隔离房间的位置提前标定好。机器人启动时加载这张地图然后根据要去的房间编号用A*算法搜索一条最短路径。A*这套算法本身就是教科书内容关键是实现时的几个决策启发函数用欧几里得距离还是曼哈顿距离我们用的欧几里得因为机器人可以自由转向不是只能横竖走open集合用什么数据结构用最小堆否则地图稍大一点就慢得离谱路径点要不要平滑要否则机器人走到拐点附近会频繁转向看起来一顿一顿的。实际跑路径的时候我们发现地图坐标和机器人自身坐标之间有一个对齐问题。怎么办在起始点让机器人原地旋转一圈用红外传感器测出四周障碍物的距离和栅格地图做匹配确定起始位姿。这个操作相当于一个简化版的定位初始化。open_set priority_queue(start) while open_set not empty: current open_set.top() if current goal: break for neighbor in current.get_neighbors(): tentative_g g[current] cost(current, neighbor) if tentative_g g[neighbor]: g[neighbor] tentative_g f[neighbor] g[neighbor] heuristic(neighbor, goal) parent[neighbor] current open_set.push(neighbor)在那种二三十平米的场地上A*的搜索时间几乎可以忽略不计但代码的工程化程度会影响后续扩展。我们把地图数据、路径点解析、路径平滑都拆成了独立的类后面想换成其他路径规划算法不用动上层逻辑。4.3 取餐机构舵机控制与柜门联动取餐机构我们做了一个四自由度机械臂顶部装了一个餐盒托架。机械臂用几路PWM舵机驱动每路舵机对应一个关节。龙芯教育派负责发控制指令STM32负责产生PWM信号。舵机的控制比较简单标准舵机一般用50Hz的PWM信号脉宽在0.5ms到2.5ms之间对应0度到180度。关键在于角度的平滑过渡——如果直接把目标角度一下发给舵机舵机会以最快速度甩过去不仅会撞到周边物体还会造成机械冲击。我们做了一段插值逻辑把角度变化分成多个小步每20ms执行一步让机械臂动作显得柔和协调。void set_servo_smooth(int channel, int target_angle) { int current_angle servo_current[channel]; int step (target_angle current_angle) ? 1 : -1; while (current_angle ! target_angle) { current_angle step; set_servo_angle(channel, current_angle); delay_ms(20); } }取餐动作的顺序我们也反复调过。先在目标点停稳放下托架打开餐柜门然后托架前伸把餐盒推到柜门边缘最后收回来、关门、播报提示音。每一步都通过限位开关检测是否到位防止机械臂在错误姿态下强行动作。这个流程看着简单但如果你直接让机械臂一次性执行完很容易出现姿态干涉和误动作。4.4 QT人机交互界面让评委一眼看懂Qt界面在这个项目里承担了两个作用一是给操作人员提供任务下发入口二是让评委快速理解机器人的工作状态。我们的界面布局很朴素左侧是站点列表点击某个站点就把配送任务加入队列中间是地图区域实时显示机器人当前的位置和规划路径右侧是日志区域打印串口指令和状态帧信息。界面底部有个大按钮叫“开始配送”按下后机器人按队列依次执行。地图绘制用到了QPainter底图是一张静态的栅格图机器人位置用一个圆形图标表示。每次收到STM32回传的位置信息界面update一下重绘区域。为了保证流畅度重绘频率控制在10Hz左右不需要更高。这里有个建议Qt界面里所有耗时操作都要丢到工作线程否则串口数据处理和地图重绘抢主线程资源界面会卡顿。我们一开始把串口读取放在主线程结果界面上机器人图标一顿一顿地跳后来把QSerialPort挪到专门的线程里用信号槽传递数据帧问题就消失了。5. 联调阶段踩过的坑与完整排查链路这一章我打算写细一些因为真正让项目从“能跑”变成“稳定跑”的不是功能代码而是联调阶段一个个填平的那些坑。如果你也是做嵌入式比赛或者类似的软硬结合项目下面几个问题大概率会遇到。5.1 串口通信乱码一次从硬件到软件的全链路排查联调第一天我们就遇到了最经典的问题龙芯教育派通过串口发0xAA给STM32STM32收到的却是完全随机的内容。面对乱码很多人第一反应是波特率不对我们把波特率从9600换到115200又换到38400问题依旧。我整理一下当时的完整排查链路用逻辑分析仪直接抓教育派TX引脚的波形观察起始位、数据位、停止位电平发现教育派发出的波形本身是正常的把USB转TTL模块接到同一串口在PC上打开串口助手手动发送同样的帧STM32能正常接收并回复说明接收端逻辑没问题于是问题锁定在教育派和STM32之间的物理连接上。仔细检查后发现教育派板载串口座默认配置成了RS232电平而STM32串口是TTL电平两者电平标准完全不匹配数据自然全部错乱解决办法是调整板子上的跳线帽把串口配置为TTL电平模式重新连接后通信立刻恢复正常。这个坑给我最大的教训是串口通信的协议和代码只是最上层硬件电平标准、共地、接口定义这些基础问题才是首先要确认的。比赛现场时间紧张遇到乱码应该先分级排查——先确认物理链路再怀疑软件配置最后才怀疑协议逻辑而不是一上来就改代码。5.2 转弯角度越转越偏里程计漂移问题程序写好后让机器人原地转90度结果实际只转了80度左右而且连续转几次之后累计误差越来越大最终机器人完全偏离预定方向。最初我以为是电机转速没跟上把PID参数调了一遍效果不明显。然后我开始怀疑编码器数据写了个测试程序让机器人以固定速度前进同时打印左右编码器脉冲数。结果发现虽然速度PID把转速控制在目标值但左右轮的编码器累计值差了几十个脉冲说明至少有一只轮子存在轻微打滑。问题找到了两轮差速底盘的里程计依赖轮子与地面的纯滚动假设但地面存在微小摩擦差异加上机器人重心不完全居中导致一只轮子负载更重更容易打滑。这种情况在加装机械臂后更加明显因为机械臂抬升餐盒时重心位置会变化。我们的解决方案是为底盘增加了一个六轴陀螺仪作为航向反馈转向角度不再只依赖编码器计算而是用陀螺仪积分修正。直行时依然用编码器累计值做距离判断但转向时用陀螺仪的偏航角作为控制目标。加入陀螺仪之后转90度的误差从10度以上缩小到2度以内机器人的走位肉眼可见地稳定了。这个事情的启发是里程计漂移是所有轮式机器人的通病编码器反馈并不是万能的多传感器融合才是工程上真正可靠的方案。5.3 机械臂舵机抖动电源不是小事情机械臂调试到第三周开始出现一个神秘问题舵机在静止状态下会高频抖动而且抖动幅度随机械臂负载增加而变大。一开始以为是PWM信号脉冲毛刺导致换了定时器、加了滤波电容都没用。后来用万用表测舵机电源电压发现问题了机械臂猛地动作时电源电压跌到4.5V以下而舵机在低于工作电压时会反复重启表现出抖动。原因很简单整个底盘和机械臂共用一组锂电池供电电机启动瞬间的大电流把电压拉垮了舵机也跟着遭殃。解决办法是给舵机单独加了一路稳压模块供电与底盘电机电源做好隔离同时舵机电源线上就近并联一个大容量电解电容吸收瞬时电流冲击。改造之后舵机抖动彻底消失。这件事对我后续做硬件设计影响很大电源是所有电子系统的基石只要供电不稳什么信号处理、滤波方案都白搭。嵌入式比赛打到最后拼的往往不是软件算法而是硬件基本功。5.4 现场演示WiFi掉线热点方案替掉路由器我们的终端交互用WiFi通信最初方案是让平板连接现场的公用路由器与教育派处于同一局域网。结果比赛现场连路由器的时候SSID很多、信号互相干扰平板时不时就断开连接。在赛场那种环境里你不可能要求主办方给你专门拉一条干净的无线网络。稳妥的做法是自建热点。我们用龙芯教育派的USB无线网卡开了一个AP热点平板直接连接这个热点避免外部网络干扰。这样通信链路独立稳定性有保证而且演示效果也更可控。从这之后我养成了一个习惯凡是现场演示用的无线设备一律自带热点或自带路由器绝不依赖公共网络。这个经验在我后来做产品演示时也一直在用。6. 复盘与代码复用建议比赛结束之后我把整个项目的源码重新整理了一遍去掉了比赛时的临时改动做了模块化重构。这个过程比比赛本身还要有价值因为很多代码在赶工的时候写得很乱但你知道它当时是怎么跑起来的等静下心来重构你才会真正理解每个模块之间的边界应该在哪里。6.1 做完这个项目后我重写的几个模块首先是串口协议层。比赛时协议是散落在各个文件里的重构之后我把它封装成一个独立的库提供send_frame()和frame_parse()两个接口上层不用关心帧结构细节。这样一来协议要换CRC校验或者增加指令只改库内部就行了。其次是PID控制模块。我把PID参数从代码里抽出来做成一个初始化结构体方便在调试时动态修改。同时增加了输出限幅和积分限幅避免积分饱和导致电机长时间满转。这些保护逻辑在比赛时没有写后来重构时补上底盘运行的安全感完全不同。再次是任务状态机。比赛时的状态机写在一个巨大的switch-case里可读性差新增一个状态就要改一大段。重构后我改用状态表驱动的方式用二维数组定义状态转移关系扩展性好了很多。最后一个项目是Qt地图绘制模块。原来每个地图元素都在绘图函数里硬编码重构后改成独立的地图数据类绘制时只需要传入地图对象。以后如果想把栅格地图换成实际的SLAM地图接口也更容易接住。这些重构之后的代码我后来在几个课设和开源项目里直接复用过尤其是串口协议和PID部分基本是嵌入式项目通用的基础件。6.2 给下一届参赛者的几点建议大赛这几年越来越卷我见过不少队伍在第一版方案里就堆了很多看起来很厉害的技术比如视觉SLAM、激光雷达、深度学习识别但到了联调阶段时间全耗在调试这些高复杂度模块上基础功能反而没有做扎实。我的建议是分阶段规划前30%时间做架构和核心链路中间40%时间做功能完善和打磨细节最后30%时间专门做稳定性测试和故障演练。演示的时候一次流畅可靠的完整流程远比一次华丽但中途卡住的流程得分高。如果比赛题目里出现了你不熟悉的新接口、新平台比如龙芯教育派这种非主流架构一定提前至少两周跑通一个最小的系统工程——哪怕是“板子上电串口发送收到Qt显示一个按钮点击变色”这种级别。这个最小系统一旦通了后面所有模块都是往这个框架里填充效率会高很多。器件选型我也是满肚子话想说。电机驱动尽量选成熟型号不要极限压榨理论参数电池容量宁可大一些也别让机器人跑到后半程电压掉到不可用机械结构件的余量留足3D打印件虽然方便但强度不够、装配误差大关键时刻真的会掉链子。最后再说一点个人体会。我们在联调串口通信和里程计漂移那段时间每天晚上最大的感受就是“又调崩了”第二天早上继续对着逻辑分析仪和示波器看波形。但恰恰是那些最折磨人的问题逼着你去查时序手册、看器件数据手册、理解电平标准这些能力才是嵌入式的内功。比赛结束后的源代码包里真正属于你自己的知识不是写着你名字的代码行号而是你为每一行代码付出的排查过程。希望这篇复盘能帮你少走一点弯路也祝你在赛场上把方案做得既稳又漂亮。本文还有配套的精品资源点击获取
返回列表