
简介这是一套自制平衡小车控制板项目源文件面向电子爱好者、嵌入式学习者和硬件开发者可用于理解两轮自平衡小车的控制板硬件设计也适合作为高校电子设计竞赛或项目的参考。压缩包内共4个文件整体约295KB包含AD格式的原理图schdoc与PCB版图pcbdoc以及立创EDA的原理图和PCB JSON工程文件方便在不同设计工具中直接查看、修改和复用。目前已有324人学习下载内容精简但覆盖完整可据此学习微控制器引脚分配、电机驱动电路、传感器接口、电源管理以及PCB布局布线等关键环节对搭建两轮自平衡小车具有直接参考价值。打开原理图能梳理各模块的连接关系查看PCB版图可了解布局布线要点而JSON工程文件则便于在立创EDA中继续调整或用于打样为自制小车改造和二次开发提供良好起点。 前阵子整理云盘翻出一个名为“河马的自制小车控制板.zip”的压缩包里面是去年花了整整一个多月做的小项目全套资料——原理图、PCB文件、固件源码、手机遥控App和3D打印底盘的STL模型都在。说句实话这东西谈不上多高深核心就是一块完全自己设计、打样、焊板、调通的小车控制板但折腾它的过程却让我从“只会用模块拼玩具”彻底过渡到了“能独立画板子做系统”。如果你也玩过玩具车也曾经用一堆杜邦线和Arduino搭过很丑的原型最后发现根本不够用那这篇就是为你准备的。1. 从“嫌弃玩具车”到决定自研控制板项目缘起1.1 玩具车套件的痛点我最早那辆玩具遥控车是那种几十块钱、带电磁转向功能的便宜货。原厂控制板是封死的只能跟着原装遥控器玩别说编程控制连想给它加个自动避障都无从下手。于是我在网上买了Arduino Nano、L298N电机驱动模块、HC-SR04超声波模块用杜邦线把它们硬接在一起。这个过程有多痛苦呢板子上堆了差不多两百根杜邦线每次改一个功能都要对着接线图查半天电源也乱电池正负极被我用鳄鱼夹夹来夹去稍不留神就反接冒火花。靠这套飞线方案原型勉强能跑但一到实际环境就露馅电机启动时电流一大整个系统电压被拉低Arduino直接复位杜邦线在震动中松脱信号时有时无更别提想把巡线、蓝牙遥控、舵机云台都加上的时候IO口完全不够用。经验告诉我模块化堆叠适合验证想法但当你想做一台“真正能稳定跑起来”的小车时必须自己画一块整合度更高的控制板。1.2 目标和技术指标所以“河马小车控制板”这个项目立项时定的目标很明确一版板子把所有常用的功能都整合进去外接线尽量少以后的新项目可以直接拿它当底盘平台。硬件规格如下表项目规格主控STM32F103C8T672MHz64KB Flash电机驱动DRV8833双H桥支持2路直流电机可差速转向供电输入2节18650锂电池标称7.4V满电8.4V板载稳压5V和3.3V两路传感器接口超声波、4路巡线、蓝牙、舵机、I2C OLED扩展接口SWD烧录口、USART1/2排针板体尺寸60mm x 80mm四颗M3安装孔从指标可以看到这就是一块典型的入门级智能小车主板不求性能炸裂但求接口齐全、稳定可靠。用STM32F103C8T6作为核心是因为它在“性能、价格、资料量”这三个维度上达到了近乎完美的平衡。单片裸片几块钱淘宝随手能买到网上例程多到看不完72MHz主频对普通小车控制来说绰绰有余。对比一下用Arduino Uno做原型固然方便但要是把它的芯片直接做到板子上封装大、引脚少、性能也弱满足不了后续扩展的需求。2. 硬件设计主控、驱动与电源的取舍2.1 为什么选STM32F103C8T6很多朋友问我为什么不直接用ESP32ESP32确实性能更强还带Wi-Fi但它的引脚大多不耐5V外围电路也比STM32复杂一些对第一次画板的人不那么友好。STM32F103C8T6是LQFP48封装引脚间距0.5mm手焊难度虽然略高但配合助焊剂和拖焊技术完全可以搞定更重要的是它的3.3V逻辑电源和全板模拟/数字接口都能稳定工作资料里经常能看到“5V容忍引脚”这一特性用来接传感器非常方便。画板时我特意把MCU的关键引脚都引到了排针上包括UART、I2C、SPI、PWM以及几个普通GPIO。这样就算以后要做新的实验也不需要重新打板从排针飞几根线就能验证功能。这块板子我后来又改了三版小车的超声波避障、巡线、蓝牙遥控、OLED显示这些功能都是直接在原有排针上测试通过后才整合进固件里的。2.2 电机驱动选型对比小车控制板最关键的电路就是电机驱动。市面上常见方案有三个L298N、TB6612FNG、DRV8833。我画板前专门列了个表对比指标L298NTB6612FNGDRV8833压降大约2V小小待机功耗较高低低最大驱动电流2A/通道1.2A/通道1.5A/通道外围电路需要大量电容/续流二极管需要少量电容极少封装15脚多瓦数SSOP-2416-QFN带散热焊盘价格便宜中等中等最终选了DRV8833核心原因是它把两个H桥集成到一个小封装里逻辑引脚兼容3.3V省去了电平转换自带过流保护电机堵转时不会烧板驱动小车轮式电机工作电流不到1A绰绰有余。封装虽然小但用热风枪配合助焊剂焊起来不难。布线时要注意DRV8833的VM引脚和电机电源进线走线要粗至少1mm宽地和逻辑地分开再单点汇合到电池负极避免电机大电流回流干扰MCU。为了进一步稳住电源我在VM入口放了一颗470uF电解电容每颗IC电源脚旁放100nF瓷片电容实践证明这能解决很多诡异的复位问题。2.3 电源树与电平适配整个板子的电源路径是这样设计的2 x 186507.4V → 电机VMDRV8833直供 ↓ 5V LDOME6211-5.0 ↓ 3.3V LDOAMS1117-3.3为什么不直接用一颗LDO从7.4V降到3.3V因为压差太大比如7.4V降到3.3V即使电流只有100mA功耗也有0.4W左右AMS1117在这种压差下发热明显。用两级降压后前级负担小后级输出也更稳定。这里有一点特别提醒DRV8833的VM必须由电池电压直供不能和逻辑5V接在一起否则电机启动瞬间会把5V拉得很低导致MCU复位。这个坑我在调试时踩过下面有专节讲。3.3V主要用于MCU、蓝牙模块、I2C OLED5V给超声波模块、舵机、巡线传感器供电。蓝牙模块我用的是3.3V逻辑电平的HC-06配合3.3V供电和3.3V串口接STM32的USART完全没问题。如果手头HC-05是5V版建议串口线上加两个电阻分压避免把芯片打坏。2.4 引脚分配我花了比较长时间规划引脚原则是PWM通道尽量集中串口留两个传感器引脚避开与复用冲突。最终分配如下功能引脚说明电机A PWM/方向PB0 / PB1定时器3通道电机B PWM/方向PB10 / PB11定时器2通道超声波 Trig / EchoPA0 / PA1PA1配置普通读IO巡线传感器PB3、PB4、PB5、PB6数字量/模拟量可选蓝牙串口PA2TX/ PA3RXUSART2调试串口PA9TX/ PA10RXUSART1舵机PWMPA7定时器1通道2OLED I2CPB8 / PB9I2C1SWD烧录PA13 / PA14板载4pin排针这个分配在实际使用中很顺手特别是把蓝牙串口和调试串口分开调试时不会互相干扰。注意如果你用STM32duino引脚编号和CubeMX里的名字可能不完全一致源码里全部用了宏定义改起来很方便。3. 固件与控制逻辑从“能跑”到“好开”3.1 为什么用STM32duino这块板子的固件我选择用STM32duinoArduino框架来写。理由很直白Arduino的生态太适合快速开发了PWM、串口、数字IO这些操作都是一行API的事比直接操作寄存器省太多时间。用HAL库也不是不行但代码量会明显增加对刚入门的朋友不够友好。工程结构上我用了主循环定时器中断的经典架构主循环负责解析串口指令、状态机切换TIM2定时器每2ms触发中断负责读取超声波传感器、更新PWM输出、刷新OLED。采用定时器中断来做周期性任务是避免主循环里忙等导致指令卡顿的关键。3.2 PWM调速与电机死区处理电机控制看起来简单实际有细节。首先PWM频率我实测在10kHz附近比较合适低于5kHz时电机会发出明显啸叫太高又可能超过DRV8833的响应能力。用analogWriteFrequency()把PWM频率设置成10kHz然后通过analogWrite设置占空比。另一个经验是电机死区。普通直流减速电机存在启动电压占空比太低时电机根本不转但直接输出0又会突然断电导致小车一顿一顿。我的处理方式是在代码里加一个死区判断// 死区补偿低于阈值时直接输出0 int deadzoneFilter(int speed) { if (abs(speed) 60) return 0; if (speed 255) speed 255; if (speed -255) speed -255; return speed; }这里的60是我实测的启动阈值不同电机可能不同接上自己的电机后要重新标定。差速转向逻辑也很简单左轮速度基础速度-转向偏移量右轮速度基础速度转向偏移量偏移量越大转弯越急。3.3 串口/蓝牙通信协议小车和手机App之间的通信我设计了一个很简短的协议每帧8字节格式是帧头0xAA、帧头0x55、指令字、数据长度、数据2字节、CRC8校验。指令表如下指令含义数据说明0x01前进数据速度0-2550x02后退数据速度0x03左转数据偏移量0x04右转数据偏移量0x05停车无0x10开启避障模式无0x11开启巡线模式无CRC8校验很关键。刚开始我偷懒没加校验蓝牙信号偶尔受电机干扰出现一个字节错误小车就莫名左右乱转。加上校验和帧头判断后误指令基本绝迹。上位机收到正确帧后会返回OK收到错误帧就返回ERR方便调试。3.4 避障与巡线的状态机避障模式的核心是一段简单的状态机伪代码如下// 避障状态机核心逻辑 enum State { IDLE, FORWARD, TURN_LEFT, TURN_RIGHT, BACKWARD }; State state FORWARD; void loop() { if (remoteMode) return; // 遥控模式优先 int distCm readUltrasonic(); // 每100ms触发一次 switch (state) { case FORWARD: if (distCm 25) { stop(); state TURN_LEFT; } else { forward(150); } break; case TURN_LEFT: turnLeft(120, 400); // 持续400ms state (readUltrasonic() 30) ? FORWARD : TURN_RIGHT; break; case TURN_RIGHT: turnRight(120, 400); state FORWARD; break; } }注意超声波触发的间隔一定要大于60ms否则测距会不稳定。我把Trig引脚放在定时器中断里每100ms触发一次主循环只读取最新测距值这样既不会卡住主循环又能保证触发时序稳定。巡线模式就简单了四路巡线传感器输出数字量我算出一个偏差值然后做最简单的P控制把偏差乘一个系数叠加到左右轮速度上。实测效果在黑白胶带场地里很稳定。4. 制板与焊接调试踩坑记录4.1 打样流程画板用的是立创EDA从原理图到PCB再输出Gerber下单整个过程花了三天。第一次打样选择了5片装价格不到十块钱典型的低成本打样体验。板子到手后看着还挺精致2层板、1.6mm厚、银色沉金工艺。焊接前记得先用万用表量一下关键电源网络的电阻防止PCB加工出现短路。元件采购方面BOM表我整理在压缩包里了大部分是0603封装电阻电容主控、驱动芯片、稳压芯片都在电商平台买的。这里有个经验先把主控和驱动芯片这类最难焊的件焊完再焊电阻电容最后焊排针和端子焊接顺序能直接影响成功率和效率。4.2 焊接经验STM32F103C8T6的LQFP48封装手焊其实没那么可怕。我用的方法是先在焊盘上薄薄涂一层助焊剂芯片对准后用烙铁稍微固定两个对角然后顺着引脚方向用拖焊法一次性扫过去。关键点是烙铁温度调到320度左右焊锡丝用带助焊剂芯的0.5mm细锡丝先多上一点锡让引脚之间连成一片再用吸锡带把多余锡吸走这样焊完引脚干净、不连锡。DRV8833的小封装同理但要注意底部散热焊盘焊接时给焊盘也加一点锡不然芯片悬空会导致过流保护误触发。4.3 问题一电机一启动主板就复位首次上电调试小车一跑起来主板就疯狂复位现象特别明显屏幕闪一下电机突然停程序从头开始执行。排查链路是这样的先用万用表量VM电压空载时7.4V正常电机启动瞬间电压跌到3.2V这就找到怀疑方向了。再用示波器看MCU的3.3V引脚也显示跌落显然问题不是MCU本身而是整个电源被电机启动电流拉垮。具体原因有两个一是电机电源走线太窄只有0.3mm大电流流过时压降巨大二是驱动电路的GND和MCU的GND在PCB上连成一片电机回流电流经过MCU接地网络时产生压差。修复方式把电机电源走线全部加宽到1.5mm在DRV8833的VM和GND之间加470uF本文还有配套的精品资源点击获取