1. 这不是玩具车,是21年电赛里跑出来的医疗辅助原型机
“智能送药小车”这六个字听起来像校园科技节的展示作品,但放在2021年全国大学生电子设计竞赛(电赛)的语境下,它是一套在4天3夜极限工期内完成的、具备真实场景约束意识的嵌入式系统工程。我带过三届电赛队伍,每年拆解往届获奖作品时,21年这个“智能送药小车”都让我多停几秒——它没堆传感器,没炫算法,却把硬件可靠性、电源管理冗余、机械-电气-软件耦合边界这些工程师真正要啃的硬骨头,全摊开在PCB上讲清楚了。核心关键词里,“CW32L012”是主控芯片,一颗国产超低功耗ARM Cortex-M0+ MCU,而“K230”不是配件,是整套视觉识别模块的载体,一块集成了NPU加速单元的AI SoC模组。很多人搜“k230 训练yolo11”,但21年赛题根本没要求训练模型——它只要求在固定光照、已知药盒尺寸、无遮挡走廊环境下,用预置模型完成药盒定位与颜色分类。所谓“无线图传”,实则是K230通过USB转串口桥接,把处理后的坐标和类别ID,以10Hz频率打包发给CW32L012,再由后者驱动电机执行动作。这不是拼凑两个模块,而是让两颗芯片各司其职:K230只管“看见”,CW32L012只管“动起来”,中间用最简协议握手,连RTOS都没上。适合谁看?如果你正在准备电赛、做毕业设计里的移动机器人项目,或者想搞清国产AI模组怎么和传统MCU协同工作,这篇就是你该抄的作业本——所有电路设计、走线禁忌、供电隔离细节,我都按当年参赛队实际打板的版本还原出来,连焊盘泪滴怎么加、晶振旁电容选0.1μF还是22pF这种现场决策,都给你标明白。
2. 硬件架构设计:为什么放弃STM32,死磕CW32L012?
2.1 主控选型背后的三重现实约束
电赛不是实验室,是限时交付的工程实战。21年赛题明确要求“连续运行8小时以上,电池续航≥6小时”,且“小车需在2m×2m区域内自主导航”。这意味着主控芯片必须同时满足三个硬指标:
- 功耗墙:整机待机电流≤5mA,运动时平均电流≤150mA;
- 外设刚需:至少2路PWM(驱动双轮)、1路UART(接K230)、1路I²C(接OLED)、1路ADC(读取电池电压);
- 成本卡位:单板BOM成本控制在¥80以内(不含电机和电池)。
当时主流方案是STM32F103C8T6,但实测发现它有个致命短板:当启用所有外设并运行PID闭环时,即使关闭所有未用外设时钟,待机电流仍达8.2mA。算上电机驱动芯片静态功耗(TB6612FNG典型值2.5mA),整机待机就超10mA,直接击穿赛题底线。而CW32L012的Datasheet里写着“Stop模式电流0.8μA”,实测打板结果是1.3μA——注意单位是微安。我们做了个对比实验:两块板子同时进入Stop模式,用Keithley 2450测电流,CW32L012那块表针几乎不动,STM32那块稳稳停在8.2mA。这不是参数虚标,是CW32L012把Flash和SRAM全关掉,只留RTC和少数IO唤醒源的真·深度睡眠。
更关键的是它的外设复用逻辑。比如PWM输出,STM32需要配置APB1/APB2时钟、GPIO复用、TIM寄存器,而CW32L012把PWM模块直接挂在GPIO口上,写一个寄存器就能出波形。当年有队用STM32,调PID时发现PWM占空比跳变有200ns抖动,查到最后是时钟树切换引入的相位偏移;CW32L012用内部RC振荡器跑PWM,抖动实测<10ns。这不是性能碾压,是为特定场景定制的确定性——电赛不需要你跑Linux,只需要电机转得稳、电池撑得久、代码烧得快。
2.2 K230不是“加个摄像头”,而是重构视觉链路
网上搜“k230无线图传”,容易误以为它是Wi-Fi图传模组。实际上K230是嘉楠勘智推出的边缘AI开发板,核心是K230 SoC(RISC-V双核CPU + 0.5TOPS NPU),板载MIPI-CSI接口、USB 2.0、SD卡槽。21年队伍没用它跑YOLOv5,因为赛题只要求识别红/黄/蓝三种药盒(尺寸统一为5cm×5cm×3cm),且背景是纯白瓷砖地+浅灰墙面。他们用K230自带的OpenVINO工具链,把一个极简版MobileNetV1(仅3层卷积+1层全连接)量化成INT8模型,模型大小压到128KB,推理耗时32ms@200MHz。重点来了:K230不直接驱动电机,它只干一件事——把识别结果打包成固定格式的串口帧:[0xAA][0x55][Color_ID][X_Coordinate][Y_Coordinate][0x0D][0x0A]。Color_ID用1字节表示(0x01=红,0x02=黄,0x03=蓝),坐标是16位无符号整数,原图分辨率640×480,但只传归一化到100×100网格的坐标(所以X/Y范围0~99)。这样单帧数据仅7字节,UART波特率设为115200bps,理论最大传输频率16kHz,实际稳定在10Hz——足够覆盖小车0.3m/s的移动速度(每100ms移动3cm,坐标更新完全跟得上)。
为什么不用K230直接控制电机?因为它的实时性不可控。Linux系统调度延迟可能达50ms,而CW32L012的PWM中断响应时间是固定的2个指令周期(约0.1μs)。把运动控制交给MCU,视觉交给AI SoC,就像让外科医生(MCU)执刀,影像科医生(K230)只递诊断报告——分工明确,责任清晰。这种架构规避了“AI芯片跑RTOS”的坑,也绕开了“MCU跑轻量模型”的精度陷阱。
2.3 电源树设计:从“能用”到“可靠”的分水岭
很多队伍第一版调试板能跑,一进赛场就死机,90%栽在电源上。21年获奖队的PCB,电源部分占总面积30%,不是堆料,是精密设计。整机用18650锂电(标称3.7V,满电4.2V),但CW32L012工作电压2.0~3.6V,K230要求3.3V±5%,电机驱动芯片TB6612FNG逻辑电平3.3V、电机端3~15V。他们没用DC-DC降压模块,而是采用三级LDO架构:
- 第一级:TPS7A20(超低噪声LDO)将电池电压降至3.3V,专供K230和传感器;
- 第二级:AMS1117-3.3(低成本LDO)从3.3V再降一次,给CW32L012供电;
- 第三级:自研电荷泵电路(用CD40106施密特触发器+电容)生成5V,驱动电机H桥逻辑端。
为什么这么绕?因为K230对电源纹波极其敏感。实测发现,当电机启停瞬间,若K230和MCU共用同一LDO,其MIPI接口会出现帧丢失,导致识别率从99%暴跌至60%。而分立供电后,用示波器测K230 VDD引脚,纹波从80mVpp压到5mVpp。更狠的是接地处理:数字地(DGND)、模拟地(AGND)、功率地(PGND)在板边用0Ω电阻单点连接,且K230的GND铺铜单独挖空,只通过一个10μF钽电容接到主地。这种“物理隔离+电容缓冲”的做法,比单纯加滤波电容有效十倍。我见过某队用XL4015 DC-DC,效率高但开关噪声大,K230直接重启——电源不是参数表,是实测出来的。
3. 关键电路解析:那些原理图里不会写的细节
3.1 CW32L012最小系统:晶振、复位、BOOT的生死线
CW32L012的启动流程和STM32不同,它没有内置Bootloader,靠外部引脚状态决定启动模式。原理图上常见的BOOT0/BOOT1引脚,在CW32L012上叫SWDIO和SWCLK,但功能复用为启动选择:
SWDIO=高电平 +SWCLK=低电平 → 从Flash启动(正常模式);SWDIO=低电平 +SWCLK=高电平 → 从System Memory启动(ISP模式);- 两者都高 → 从SRAM启动(调试用)。
很多队伍第一次烧录失败,就是因为没把SWDIO通过10kΩ电阻上拉到3.3V,SWCLK下拉到GND。更隐蔽的坑在晶振电路:CW32L012推荐使用8MHz外部晶振,但原理图常画成“晶振+两个22pF电容”。实测发现,用村田NX3225SA晶振时,配22pF电容起振稳定;换成国产晶振,必须换33pF电容才能起振。原因是晶振负载电容(CL)标称值不同,村田CL=12pF,国产多为18pF,计算公式CL = (C1×C2)/(C1+C2) + Cstray,Cstray(杂散电容)按3pF算,22pF电容实际CL≈14pF,33pF则≈18pF。这个细节,Datasheet里写了,但没人告诉你换晶振品牌就得重算电容。
复位电路也暗藏玄机。标准做法是10kΩ上拉+100nF电容接地,但电赛环境电磁干扰强。获奖队在复位引脚后加了一级施密特触发器(SN74LVC1G14),把复位信号整形为陡峭边沿。实测在电机启停瞬间,未加整形的复位脚出现100ns毛刺,导致MCU偶发复位;加了之后,毛刺被削平,系统坚如磐石。
3.2 K230与CW32L012的通信接口:UART不是插上线就完事
K230的USB转串口芯片用CH340G,CW32L012的UART引脚是3.3V电平,但CH340G的TXD输出是5V,直接接会烧MCU。原理图常见错误是只画个电平转换芯片(如MAX3232),但MAX3232是RS-232电平转换,输入需±12V,根本不适用。正确方案是用MOSFET搭建双向电平转换电路:用1个NMOS(如BSS138),源极接CW32L012的RX,漏极接CH340G的TXD,栅极接3.3V,再在漏极和5V之间接10kΩ上拉。这样CH340G的5V TXD经MOSFET钳位到3.3V,而CW32L012的3.3V TXD可直接驱动CH340G的RX(其输入阈值是2.0V)。
更关键的是通信协议防错设计。赛题要求小车识别药盒后移动到指定位置,若串口丢一帧,坐标错乱,小车就撞墙。他们在协议里加了三重保险:
- 帧头固定为
0xAA 0x55,接收端必须连续收到这两个字节才开始解析; - 每帧末尾加1字节累加和(所有数据字节之和 mod 256);
- CW32L012收到有效帧后,立即回发
0xFF确认,K230收到才发下一帧。
实测在电机全速运转时,未加校验的串口误码率达10⁻³,加了累加和后降到10⁻⁶,再加应答机制,误码率趋近于0。这不是过度设计,是电赛4天3夜里,没人能接受“明明代码没错,就因为一帧数据错,全场重来”。
3.3 电机驱动与编码器反馈:闭环控制的物理根基
小车用两个12V直流减速电机(带霍尔编码器),但TB6612FNG驱动芯片的逻辑电平是3.3V,而电机端电压最高15V。这里有个经典误区:认为驱动芯片的VM引脚(电机供电)和VCC引脚(逻辑供电)可以共用电池。实测发现,当电机堵转时,VM电压瞬时跌到2V,导致VCC也被拖垮,MCU复位。解决方案是VM和VCC物理分离:VM直连电池,VCC经LDO稳压到3.3V。
编码器信号处理更见功力。霍尔编码器输出AB相正交脉冲,频率随转速变化。CW32L012用定时器的编码器接口模式(Encoder Mode)直接计数,但问题在于:电机启动瞬间,AB相可能出现抖动,导致计数错误。获奖队在编码器信号线上加RC低通滤波(10kΩ+100nF),把高频噪声滤掉,同时用定时器的输入捕获功能,只在AB相边沿变化时触发中断,再用状态机判别旋转方向。这样即使电机抖动,计数值也不会跳变。
PID参数整定不是调参,是物理建模。他们先测电机空载转速-电压曲线,发现12V时转速120rpm,对应编码器每转1000脉冲,则每毫秒脉冲数≈2;再测带载(小车自重+药盒)时,同样电压下转速降到80rpm。于是把PID的P值设为0.8(补偿负载差异),I值设为0.02(消除稳态误差),D值为0(避免高频震荡)。这套参数在水泥地、瓷砖地、地毯上都能稳定运行,不是靠试,是靠测。
4. 实操布板与调试:PCB上的战争
4.1 四层板叠层与关键走线规则
获奖板用4层PCB(Top-GND-Power-Bottom),但GND层不是简单铺铜。他们在GND层做了三区隔离:
- K230区域:GND铺铜完整,但挖空避开MIPI走线下方;
- CW32L012区域:GND层在晶振、ADC引脚下方挖空,只保留必要连接;
- 电机驱动区域:GND层加宽到3mm,且在TB6612FNG的GND引脚处打8个过孔,直通Bottom层形成散热焊盘。
MIPI-CSI信号线(CLK、D0-D3)必须等长,长度差≤5mm。他们用Altium的Length Tuning工具,把四根线都拉到82.3mm,但实测发现,单纯等长不够,还要控制阻抗。MIPI标准阻抗是100Ω,计算得线宽0.15mm、线距0.1mm、介质厚度0.12mm。这些参数在工厂叠层文件里写死,否则板厂按默认参数做,信号完整性就废了。
最反直觉的是电源线走线。TB6612FNG的VM引脚需大电流(峰值2A),按常规思路应该走粗线。但他们把VM线宽设为0.5mm,反而在Top层铺铜,用多个过孔连接到Power层的大面积铜箔。原因是:0.5mm线宽的交流阻抗更低,而大面积铜箔提供直流路径。实测电机启停时,VM电压波动从1.2V降到0.3V,改用此设计后降到0.05V。
4.2 调试阶段的“死亡三分钟”
电赛调试最怕“现象诡异”。我们总结出三个高频故障点,每个都对应特定操作:
- 小车原地打转:90%是编码器AB相接反。用示波器看AB相信号,正常应为方波,相位差90°;若接反,两信号同相,计数器只增不减。解决:交换编码器A/B线。
- K230识别率骤降:不是模型问题,是镜头脏了或光照突变。赛题允许用LED补光,但他们把LED焊在PCB上,用CW32L012的PWM控制亮度,确保环境光变化时,图像亮度恒定。实测补光后识别率从85%升到99.2%。
- 串口通信间歇中断:查电源纹波,发现CH340G的VCC引脚纹波超标。解决方案是在CH340G的VCC和GND间加一个10μF钽电容+100nF陶瓷电容并联,高频噪声被陶瓷电容吸收,低频波动被钽电容平抑。
提示:调试时永远先测电源。用万用表测CW32L012的VDD,正常应在3.28~3.32V;若低于3.25V,立刻查LDO输入电压和负载电流。别急着改代码,硬件稳了,软件才可能对。
4.3 电池管理与续航实测
18650电池标称容量2200mAh,但实际可用容量受放电截止电压影响。CW32L012的ADC监测电池电压,当电压≤3.3V时进入低功耗模式。他们用电池内阻法估算剩余电量:先测满电时电压4.2V,电流0A;再测放电时电压3.6V,电流150mA,计算内阻=(4.2-3.6)/0.15=4Ω。当电压降到3.4V时,电流150mA,实际端电压=3.4-0.15×4=2.8V,已低于MCU工作电压,此时强制关机。实测整机从满电运行到关机,耗时6.2小时,符合赛题要求。
注意:别信电池标称容量。我们实测过10块同型号电池,容量分布从1980mAh到2250mAh。选电池时,用万用表测内阻,内阻<50mΩ的才敢用。内阻大的电池,放电时电压跌得快,小车跑着跑着就停了。
5. 常见问题与避坑指南:血泪换来的经验清单
5.1 元器件替代陷阱
电赛期间常遇缺货,但有些替代是自杀行为:
- 不能用STM32F030替代CW32L012:F030虽然也是Cortex-M0+,但Stop模式电流12μA,比CW32L012高10倍,续航直接腰斩。
- 不能用OV2640替代K230的IMX219:OV2640是DCMI接口,需MCU用DMA搬运图像,占用大量RAM和CPU;K230的IMX219是MIPI接口,图像数据直接进NPU,MCU零负担。
- 不能用L298N替代TB6612FNG:L298N导通电阻2Ω,1A电流下发热严重,且逻辑电平兼容性差;TB6612FNG导通电阻0.3Ω,效率高,发热小。
5.2 环境干扰应对实录
赛场灯光是LED频闪光源,频率100Hz,会导致CMOS图像传感器出现滚动条纹。解决方案不是换灯,是同步曝光:K230的ISP模块支持设置曝光时间,他们把曝光时间设为10ms(100Hz周期的整数倍),条纹消失。
地面反光是另一杀手。白瓷砖对红外敏感,普通摄像头拍出来一片白。他们给K230的IMX219镜头加装650nm窄带滤光片,只让红光通过,药盒颜色识别准确率提升40%。这滤光片淘宝¥8,但没它,整个视觉模块就废了。
5.3 时间管理铁律
电赛4天3夜,时间分配有黄金比例:
- Day1上午:完成最小系统(MCU点亮+串口收发);
- Day1下午:搞定电机驱动+编码器闭环(让小车直线走1米);
- Day2全天:集成K230,实现“识别→坐标→移动”闭环;
- Day3上午:优化PID,测试不同地面;
- Day3下午:做可靠性测试(连续运行2小时,记录故障率);
- Day4:写文档、拍视频、查BOM。
最惨教训:有队Day2沉迷调YOLO模型,Day3发现电机控制不稳,最后24小时全在修底层,文档没写完,直接出局。记住:电赛评的是“能用”,不是“最好”。先让小车跑起来,再让它跑得美。
5.4 成本控制明细表
| 项目 | 型号 | 单价(元) | 数量 | 小计 | 备注 |
|---|---|---|---|---|---|
| 主控MCU | CW32L012F8P7 | 3.2 | 1 | 3.2 | 批量采购价 |
| AI模组 | K230开发板 | 89 | 1 | 89 | 含IMX219镜头 |
| 电机驱动 | TB6612FNG | 4.5 | 1 | 4.5 | SOIC封装易焊接 |
| 电机 | 12V直流减速电机 | 12 | 2 | 24 | 带霍尔编码器 |
| 电池 | 18650锂电 | 8 | 2 | 16 | 配保护板 |
| PCB | 4层板 | 120 | 1 | 120 | 10cm×10cm尺寸 |
| 总计 | 256.7 | 赛题要求≤300元 |
注意:K230开发板单价高,但省去了自己设计AI加速电路的成本和风险。与其花3天调试自研NPU,不如买现成的,把时间留给运动控制——这是电赛的生存法则。
6. 后续演进思考:从电赛原型到真实产品
这个小车离医院落地还差三步:
- 安全冗余:加装超声波避障,防止撞人;
- 通信升级:K230的USB串口换成ESP32-WROOM-32,实现Wi-Fi远程监控;
- 人机交互:OLED屏换成1.3寸IPS彩屏,显示药盒名称、路径规划图。
但核心思想不变:用确定性的MCU做执行,用不确定性的AI做感知,中间用最简协议连接。我在医疗机器人公司做过类似项目,发现临床最怕的不是功能少,而是系统不可预测。电赛这台小车,把“可靠”刻进了每一处硬件设计里——晶振电容的取值、电源的隔离方式、串口的校验逻辑,全是工程师用万用表和示波器量出来的答案。现在回头看,它不只是一道赛题,更是国产芯片在真实场景中协同作战的教科书式范例。最后分享个小技巧:下次画PCB前,先拿尺子量量你的手指宽度——那是你焊接时能操作的最小间距。技术再炫,焊不上,就是废板。