☰
大模型负责说,STM32负责做:桌面机器人双芯片分工解析
2026/9/26 15:06:50 网站建设 项目流程

前阵子做桌面机器人原型时,一个刚接触这个方向的算法同学问了我一个问题:“我们接的对话模型都已经那么强了,为什么主板上还是非要焊一颗 STM32?让大模型直接说话不也能响应吗?”这个问题并不外行,反而问到了机器人开发最容易混淆的岔路口上。很多人理解的“会聊天的机器人”,约等于“一个能联网的智能音箱”——声音进去,文字出来,再让合成音把话读出来,齐活。但真正把一个会聊天的机器人搬上桌面,让它睁眼、转头、点头、跟着人走、被摸头时有反应,事情就没这么简单了。

这篇内容主要想讲清楚一件事:在大模型负责“说什么”的同时,必须有一颗本地、实时、确定性的控制芯片来负责“怎么做”和“保安全”。文章会从硬件分工、实时性账目、典型外设场景、选型思路和踩坑实录几个方面展开,适合正在做桌面机器人、交互机器人、甚至带机械臂的DIY项目的朋友参考。如果你手头已经在用 Linux 主板跑大模型,但总觉得机器人动作迟顿、偶尔抽风,看完这篇应该能定位到问题根源。

1. 机器人身上的两套神经系统:大脑负责聊,小脑负责活

1.1 “会聊天”只是机器人的第一层外衣

先剥开“会聊天”这层皮。一个完整的对话机器人,从用户开口到机器人做出口头回应,大概涉及声音采集、端点检测、语音转写、大模型推理、回复文本合成、音频播放这么一条链路。这里面每一步都是弱实时甚至非实时的——网络抖动一下,模型推理慢半拍,回复晚两秒,用户顶多觉得它“反应有点慢”,不会造成什么物理后果。

但同一个机器人如果长着胳膊、脑袋、轮子,情况就完全变了。用户说了一句“转过来看我”,机器人需要先把脖子电机转到目标角度;说“往前走一点”,轮子要开始转,还要在撞到桌腿前停下来;聊到一半电池没电了,还得优雅地进入待机而不是当场死机。这些动作如果也走“云上推理再回来执行”这条路,等模型算完,机器人要么已经撞上东西,要么电机堵转发热,要么干脆在关键动作上顿挫。

所以我在做方案的时候,一直把机器人拆成两套东西来看:一套是“认知系统”,负责听懂、生成、决策,门槛高、延迟可以高;另一套是“行为系统”,负责感知环境、执行动作、保护硬件,延迟必须低、行为必须可预期。前者靠主控 SoC 加网络,后者必须在本地有一颗能打实时账的 MCU。

1.2 STM32 在这套分工里到底扮演什么

STM32 在聊天机器人里的角色,更像脊髓和脑干那一层。它不负责“思考今天聊什么”,但负责“让眼球平滑地转向发声的人”“让底盘精确地停在离人半米的位置”“让电池低于阈值时先保住系统不掉电”。这些都是几毫秒到几十毫秒级别必须给出响应的事情,交给一颗依赖 Linux 调度、随时可能被后台任务抢占的通用处理器,不靠谱。

这颗 MCU 的不可替代性可以归结为四个词:确定性、实时性、外设直达、低功耗安全兜底。确定性意味着同样的输入永远在同样时间内得到输出;实时性意味着中断优先级的抢占是硬件保证的;外设直达意味着 PWM 波形、编码器计数、I2S 音频流都有专用硬件电路接管,不占 CPU;低功耗安全兜底则意味着即使主控死机,MCU 还能维持关键继电器、灯光、电机抱闸状态,让机器人不至于当场失控。

把话说得更直白点:大模型是“情商”,STM32 是“求生本能”。你可以靠情商聊得天花乱坠,但碰到滚烫的电机,只有求生本能才能让机器人活过今天。

2. 从“听到声音”到“转过头来”:毫秒级时序的真账

2.1 一个普通的“唤名转头”动作,背后串了多少条中断链

很多纯软件背景的朋友对“实时响应”没有体感。我举一个实际例子:机器人正在桌面待机,用户叫它名字,它需要转头看向用户,同时说一句“我在”。这个动作看起来简单,但底层要同时跑这几路信号:

  • 麦克风(通常接在 STM32 的 I2S 或 PDM 接口上)持续采集音频,通过 DMA 搬运到内存环形缓冲区。MCU 里跑语音唤醒模型,识别到唤醒词后,置一个事件标志;
  • 事件标志唤醒音频前端线程,把缓冲区内的音频帧打包,通过 UART 发给主控 SoC,主控再把它丢给云端语音服务;
  • 与此同时,六轴 IMU 以 1kHz 频率在中断里读出加速度和角速度,姿态解算持续更新。STM32 要判定当前机器人是静止还是被拿起来,头部转到什么位置;
  • 头部两个舵机由定时器 PWM 驱动,编码器反馈实时回传,PID 调节在 1kHz 控制周期里完成角度闭环;
  • 底盘如果也在动,还要叠加编码器测速、超声波避障、电机电流采样。

这一串事情里,音频要保证不死音、不爆音;姿态数据要保证时间戳准确,不然融合算法直接飘;PWM 要保证频率和占空比更新无毛刺;串口要保证和主控之间的通信不丢帧。每一个环节都依赖硬件定时器、DMA、中断优先级管理。STM32 这种芯片的设计目标就是把这类实时任务用硬件外设包掉,让 CPU 只做裁决,而不是去数引脚电平。

2.2 通用 Linux 主控为什么包不圆这件事

有人会问:用树莓派或者 RK3588 这种主控,不是也能通过 GPIO 输出 PWM、也能读编码器吗?理论上能,但工程上很痛苦。Linux 的调度周期是毫秒级抢占,普通用户态进程随时可能被其他进程打断几十毫秒。你确实可以写内核驱动、用 PRU 或者实时补丁去改善,但每增加一层抽象,延迟的不确定性就大一分。

打个比方:你让一个总经理去给员工泡茶,他不是不会,而是他手头正在开季度复盘会,一个紧急电话进来,这杯茶就可能等二十分钟。机器人控制恰恰是另一个极端——舵机需要每 20ms 收到一次新占空比,电机驱动器需要每 1ms 收到一次电流指令,错过一拍,电机就开始抖、发热、甚至失步。用非实时系统去直接干这种活,等于让总经理同时干十个烧水壶的活,迟早有壶烧穿。

而 STM32 的中断响应是硬件级别的:一个外部中断从触发到进入 ISR,通常是十几个时钟周期的事,即便跑 72MHz 主频,也在微秒量级。定时器溢出、DMA 搬运完成、编码器计数溢出,这些都是由硬件直接触发事件,不需要操作系统帮忙排队。这就是为什么实际项目里,大家心照不宣地把 SoC 和 MCU 拆开:SoC 干重脑力活,MCU 干全天候体力活。

3. STM32 在聊天机器人里实际要管的那些具体差事

3.1 音频采集与语音前端:先把人声洗干净再上传

聊到语音,很多人以为麦克风直接连着主板的 USB 声卡就行。但做带唤醒词的交互机器人,我更建议把音频采集放在 MCU 侧。原因有三个:一是唤醒词检测要在本地低功耗状态下常驻,不能每次唤醒都去拉响主控;二是音频流需要用 DMA 连续采样,保证没有断点;三是本地可以做简单的 VAD(语音活动检测)和回声参考信号采集,后续做双麦克风降噪时,MCU 可以直接同步采集两路数据。

STM32 接数字麦克风非常成熟,PDM 接口或者 I2S 接口都有现成外设。实际项目中常用方案是:STM32 用 I2S DMA 双缓冲采集 16kHz/16bit 单声道音频,每帧 10ms;主控 SoC 通过串口或 USB 从 STM32 那边拿音频帧。这样主控那边不用管底层音频驱动,只处理业务逻辑。我在自己的项目里用 STM32F407 接了两颗 PDM 麦克风,做 64 倍过采样,再把数据降到 16kHz 发送,整条链路 CPU 占用不到 10%。

如果你把语音采集放在主控侧,也不是不行,但唤醒词识别就得常驻在 Linux 上跑,意味着主控永远不能深度睡眠。一颗空闲时 800mA 电流的 SoC 和一颗待机 10μA 的 STM32,对于电池供电的桌面机器人来说,差距就是“隔夜掉电 50%”和“隔夜掉电 2%”的区别。

3.2 运动执行与传感器融合:编码器、测距、六轴 IMU

聊天机器人要“活”,离不开动。最简单的桌面机器人至少要有头部俯仰和左右偏航两个自由度,稍微进阶一点加轮式底盘。这时 STM32 的定时器外设就派上大用场了。

驱动舵机或直流电机,本质上是让定时器产生频率可调、占空比可调、相位可控的 PWM。STM32 的高级定时器还支持互补输出和刹车功能,配合电机驱动器可以做硬件层面的过流保护。读取轮子转速则靠编码器接口:把 AB 相信号接到定时器的编码器模式,硬件自己判断正反转并累加计数。这就是为什么很多人搜“stm32 编码器程序”会发现,核心代码其实就是初始化一个定时器、配置成编码器模式、开中断读值,根本没有复杂的数学运算。真正需要花心思的是计算轮速、里程、速度环 PID 的参数匹配。

测距一般分两种:超声波和激光。超声波模块用 GPIO 触发、回波计时就能测距,但精度受限;STM32 有专门的输入捕获功能,可以精确捕捉回波上升沿和下降沿,配合定时器得到微秒级时间差。我在底盘避障里实测过,用 STM32 输入捕获读超声波,误差可以控制在 1cm 以内,比用主控读 GPIO 电平稳定得多。

IMU 数据融合也放在 STM32 侧更合理:六轴模块通过 SPI 或 I2C 以 1kHz 速率输出原始数据,STM32 跑互补滤波或卡尔曼滤波,输出姿态角给主控。这样主控拿到的不是平均过、有抖动、时间不齐的原始数据,而是已经稳定的姿态估计。而且 IMU 的时间戳由 MCU 统一打点,后续和电机编码器数据做联合处理时不会出现“谁先谁后”的扯皮问题。

3.3 关节与总线的连接:RS485 控制伺服电机有什么好处

桌面机器人不一定只用普通舵机,如果要做手臂或者腰部的精确回传,很多方案会用支持 RS485 的伺服电机(用私服电机做关节控制)。此时 STM32 的优势更加明显:它自带 UART,配合外部 RS485 收发器,就能搭一条半双工总线,挂多个伺服节点。

RS485 控制伺服电机,最核心的是时序。半双工总线意味着同一时刻只能由一个节点发数据,从“发送指令”到“切换到接收”,必须严格掌控 DE 引脚的电平切换时机。这活儿用 STM32 做,可以在一个定时器的中断里精确切换;如果放在 Linux 上,切换时机被调度器毁了,一帧控制指令之间抖动几个毫秒,伺服轴就会走着走着顿一下。

实际使用中我习惯把控制周期固定成 10ms:TIM 每 10ms 触发一次中断,在中断里向总线发送目标位置/速度指令,然后立刻切到接收模式,等待回读位置和电流。这样即使主控侧大模型推理占满了 CPU,电机控制循环的节拍也不会乱。

3.4 电源与充电管理:避免机器人聊着聊着就“断电僵住”

这是最容易被忽略的一块。会聊天的机器人一定带电池,带电池就一定涉及低电量检测、充电状态管理、掉电时序。我见过太多原型项目,因为缺了这一层,机器人在演示中出现过“正聊得开心,砰一下关机”的名场面。

STM32 的 ADC 可以用来采集电池电压和充电电流。如果电池电压低于阈值,MCU 可以直接通知主控保存对话状态,再关掉舵机供电,等待用户插上充电器。充电芯片的状态引脚接在 STM32 的 GPIO 上,充满、充电中、异常三种状态都能被实时监控。上电时序也由 MCU 管理:先让 MCU 自己跑起来,等电压稳定了,再逐步打开主控电源和电机电源,避免刚插电那一下浪涌把 SoC 打死。

这一层由 STM32 来做,核心逻辑不是复杂,而是不能断。如果让一个运行着完整操作系统的 SoC 去管断电,一旦系统因为高负载忙不过来,就可能错过电池低压告警。而 MCU 没那么多任务,电源管理的中断优先级能放最高,保证了“断也要断得体面”。

4. 桌面陪伴机器人主控板选的选型思路与通信协议设计

4.1 从 F103 到 H7:不同定位芯片怎么挑

一提到 STM32,很多人第一反应是“蓝板子 F103C8T6”。这颗芯片确实便宜量大,做舵机驱动、传感器采集、串口转发完全够用。但它资源有限:SRAM 只有 20KB,主频 72MHz,跑音频缓冲加姿态解算,内存会开始紧张。我的个人建议是分三档来选:

项目复杂度推荐芯片核心理由
单舵机、简单语音唤醒转发STM32F103C8T6成本低,资料多,工程简单
多自由度头部/底盘 + 音频采集 + IMUSTM32F407VET6168MHz,有 I2S 和 CAM 接口,DSP 指令加速,内存足够
带屏幕渲染、需要外扩存储、未来上 Linux 虚拟机STM32H743480MHz 主频,AXI 总线矩阵,适合复杂中间层

说实话,F103 的生态资料最多,淘宝上随便买一片,接线出问题的概率极低。但你要在它上面同时跑音频环形缓冲、姿态解算和伺服控制,20KB SRAM 会很快见底,而且 DMA 通道紧张,外设之间争总线的现象比较明显。F407 是我目前在桌面机器人上最常用的一颗,它自带 FPU 和 DSP 指令,跑浮点姿态解算很轻松,还有完整 I2S 外设来接数字麦克风。H7 则适合那种主控 SoC 资源腾不开、想让 MCU 多干点活的场景。

工程上我还有个经验:如果只是验证功能,优先用 F103 或 F407 加最小系统板而不是直接画 PCB,因为原型阶段你一定会改引脚定义。等整个框架跑通了,再根据资源占用情况选最终型号,做集成板。

4.2 主控与 MCU 之间的串口协议设计:宁可多写一行解析,也不贪省事

说完芯片,说说两个处理器之间怎么通信。目前最常见的组合是 Linux 主控 + STM32 通过 UART 连接,速率从 115200 到 921600 不等。这里最大的坑不是速率,而是帧协议。

我强烈建议从一开始就设计一个带帧头、长度、命令字、校验和的协议,而不是直接发裸字符串。裸字符串调试时很爽,但一旦你要在一条连接上同时传音频数据、传感器状态、运动指令、电量信息,裸字符串会变成一场灾难:解析容易错位,数据边界不清晰,主控和 MCU 两边改来改去就再也没法对齐了。

我的常用帧格式类似这样:

帧头0xAA55 | 长度(2字节) | 命令字(1字节) | 数据区(n字节) | CRC16(2字节)

所有多字节数据用小端序,控制周期和上报周期分开。比如 IMU 姿态 10ms 上报一次,运动指令 20ms 刷新一次,电池状态 500ms 上报一次。MCU 收到主控指令后,必须回一个 ACK 帧说明是否执行成功。这样主控侧可以做超时重发,而不是发了就当成功。

还有一点经验很重要:解析状态机里一定要做“连续错误计数”,如果连续若干帧 CRC 错误,说明物理链路有问题(波特率不匹配、电平不稳、干扰),要主动报错而不是默默丢帧。否则机器人会出现“偶尔愣一下”这种极难定位的灵异问题,查到最后往往是串口帧丢失。

4.3 中断优先级、临界区和 SysTick:主控代码中真正容易翻车的地方

如果说选型和协议是图纸,那条中断设计就是施工规范。永 在 STM32 工程的裸机编程或 FreeRTOS 嵌入式开发里,翻车最多的就是中断优先级配置。举三个高频事故:

第一个是HAL_Delay卡死问题。STM32 的标准库默认用 SysTick 提供delay_ms,但如果你在初始化后期自己改写了 SysTick 的中断优先级,或者 SysTick 被 FreeRTOS 接管,再在中断回调里调用HAL_Delay,系统会直接死锁——因为HAL_Delay依赖 SysTick 中断去翻转计数值,而 SysTick 中断优先级比当前中断低,当前中断一直不退出,SysTick 永远没机会执行。

第二个是 JTAG 引脚被复用成 GPIO。F103 的 PA13、PA14、PA15 和 PB3、PB4 默认是 SWD 调试口。很多人画板时为了省引脚,直接把 PA13 当按键、PA15 当 LED,结果程序一烧进去,调试口功能被禁用,之后再也没法用 J-Link 连芯片。遇到这种情况,最快救法是拉 BOOT0 进系统存储器,串口 ISP 全片擦除,再重新烧录。但这会浪费大半天时间。所以我建议:任何板子都要把 SWD 引脚单独引出,哪怕 PCB 上不焊排针,也要留下测试点。

第三个和“stm32 库函数和标准库有什么区别”这类老问题关联在一起。新工程建议用 HAL/LL 库,但很多人从标准库转过来时,会对 HAL 的句柄结构、超时机制不习惯。最常见的坑是 HAL_UART_Receive 默认是阻塞等待,如果不小心在中断里调用,整个中断服务函数会被拖死。我的习惯是:中断里只置标志位,实际接收逻辑放在主循环或专用任务里处理;需要用 DMA 就用 DMA 空闲中断,别靠轮询。

5. 踩坑实录:为什么你的机器人总会“呆住”或“死机”

5.1 看门狗:不要让主控卡死拖垮 MCU 执行

“会聊天”功能上线后,最容易出的问题是大模型推理线程卡住,主控 SoC 假死。如果 MCU 侧电机控制、传感器采集还继续正常跑,机器人看起来挺正常,但已经没人指挥它了。这时候如果没有看门狗,机器人就会顶着一个死寂的主控继续做无意义的运动——比如一直原地打转,直到撞墙。

我给机器人的标准配置是:STM32 里开独立看门狗(IWDG),主控通过心跳帧定期给 MCU 喂狗。如果 MCU 在 1~3 秒内没收到心跳,先执行兜底动作:电机刹车、舵机回到安全位置、蜂鸣器报警、LED 闪烁;再等一个宽限期,若主控还没恢复,就执行整机软关机。这样即使大模型整个崩了,机器人也是安全姿态,而不是“僵尸漫步”状态。很多人以为看门狗只是防 MCU 自己死机,其实跨芯片的心跳机制更重要。

5.2 电机的“堵转发热”检测:电流采样不能省

聊天机器人多了电机之后,另一个高频事故是堵转。头被东西卡住,或者用户拿手按住舵机臂,电机过流发热,轻则烧舵机,重则烧驱动板。这个问题的检测完全可以在 MCU 侧解决,核心是采样电机电流。

我的方案是用 INA240 之类的电流采样运放把电机电流放大后接 MCU ADC,然后用 DMA 循环采样。控制程序每隔 10ms 判断一次电流有效值和持续时长,超过阈值就切断该路 PWM,上报主控“运动异常”。这比靠舵机内的电位器回读判断更直接——堵转时电机电流会立刻飙升,电位器读数却可能还是目标位置附近,等到它偏出去已经晚了。

其实上面这个逻辑就是工业机器人里的“转矩限制”思想。桌面机器人虽然小,但这个保护机制一点不能省,否则演示现场用户随手拨一下机器人脑袋,几十块钱的舵机就报废了。

5.3 与 VSCode 和 OpenCode 生态的协作:代码不用贪多,结构要留好

最后聊点团队协作层面的经验。现在很多人用 VSCode 加插件写 STM32,配合 CMake 或 PlatformIO,比 Keil 的工程管理灵活很多。我自己现在习惯用 VSCode + CMake + arm-none-eabi-gcc 维护 MCU 代码,不用 Keil 的原因之一是:Keil 工程在多人协作时,文件路径和编译选项差异太大,Git 合并容易出事;而 CMake 可以把源码、驱动、应用分开组织,CI 也能跑。如果你刚开始搭工程,别把模块写成一坨,尽量按drv_(底层外设)、app_(业务逻辑)、protocol_(通信协议)分层,后面无论换芯片还是加功能,都轻松得多。

至于在机器人里用大模型做“具身智能”——比如根据对话内容决定转头的幅度、根据情绪决定眼睛亮什么颜色——这些高层决策逻辑放在主控 SoC 或云端没问题。但底层执行如果变成“模型推理一个动作,再让 MCU 执行一个动作”,中间延迟就会高到不可接受。我现在推进项目的一个原则是:能离线执行的决策,尽量在 MCU 侧静态默认;必须在线推理的决策,给足超时回退和看门狗保护,绝不把整个机器人的安全系在大模型的响应时间上。

最后说点个人习惯

我自己踩过几次坑之后,现在动手做一台会聊天的机器人,一定会先问三个问题:唤醒到第一句回应总延迟能不能控制在 1.5 秒以内;MCU 和主控断联后机器人会不会安全停下;电池低压时整机链路从上到下按什么顺序断电。这三个问题只要有一个答不上来,我就知道主控板和 STM32 的分工还没理清楚。做机器人这件事,会聊天让人喜欢它,但让它安全地活着、随时响应、不抽风,才是真正区分“玩具”和“作品”的分水岭。希望这篇内容能让更多人看到那颗藏在对话框背后、整天忙着跑中断和定时器的 STM32 的价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询