
简介这是一套基于STM32微控制器的六足机器人设计与实现完整工程面向嵌入式系统学习者、机器人竞赛团队以及毕业设计或产品原型开发工程师资源重点涉及STM32、ARM、嵌入式硬件与单片机可帮助解决从硬件选型、电路设计到底层驱动、运动控制算法落地的全流程问题。硬件部分以STM32F4系列为核心详细覆盖微控制器选型、电源管理、电机驱动电路、陀螺仪与加速度计等姿态传感器接口、蓝牙或无线通信以及通用输入输出扩展等设计要点软件部分则给出模块化固件架构基于实时操作系统完成多任务调度采用比例积分微分控制算法实现精确关节控制并设计了直行、转弯、爬坡等步态模式和动态平衡策略兼顾代码与算法细节。压缩包共八百五十六个文件体积四十六点四八兆字节内容以C语言源码、编译中间文件、十六进制固件和开发环境工程配置为主体同时包含原理图、印制电路板文件、文档、图片、元件清单、工艺数据以及两款远程控制安卓安装包便于对照硬件连接、固件逻辑和手机操控端进行系统学习。目前已有1103人学习下载资源内保留了多版本迭代与调试记录特别适合需要从零搭建六足机器人、优化步态或进行二次开发的读者可将其作为完整参考模板快速上手。1. 从舵机抖动到六足站稳为什么这个标题值得做六足机器人最吸引人的地方是它同时踩在机械设计、嵌入式控制和运动学算法三条线上。相比双足六足在静态稳定性上有天然优势——任意时刻至少有三条腿着地重心不用像双足那样时刻放在支撑多边形内相比轮式它能跨障碍、爬坡、在不平地面保持姿态。而 STM32 之所以成为这类项目的主流控制核心不是因为性能最强而是因为它的定时器资源、PWM 输出通道和生态积累刚好卡在六足机器人的需求点上18 路舵机脉冲、IMU 读取、串口调试、传感器融合一块 20 元上下的芯片都能覆盖。这篇博文按我实际做过和反复踩过的路径来写从舵机选型到逆运动学从 PWM 分配到避障逻辑目标是让你拿到原理图和自己写的代码能让样机站起来、走起来、撞到东西会拐弯。适合正在做课设、毕设或入门足式机器人的人也适合想从固定翼或小车转过来的嵌入式工程师。2. 六足机器人的硬件平台与自由度配置2.1 舵机选型从扭矩到响应速度的匹配六足每条腿通常用 3 个舵机分别控制髋关节左右摆、大腿关节前后抬、小腿关节上下踏18 路舵机是主流方案。少自由度比如每条腿 2 个舵机的设计也能走但步态灵活性明显受限转向时姿态调整困难后期想叠加姿态补偿几乎没有余量。舵机选型的优先顺序是扭矩、工作电压、响应速度、重量。注意舵机标称扭矩与实际可用扭矩之间要留 30% 以上的余量六足行走瞬间单腿受力是静态受力的大约 2 到 3 倍。估算方法假设单腿质量 0.15 kg含舵机和结构件大腿长 70 mm髋关节到重心的力臂约 85 mm静态扭矩约 0.13 N·m也就是 1.3 kg·cm。但行走时前腿触地冲击、身体侧倾、转向时侧向分力都集中在支撑腿上所以单腿髋关节舵机至少按 4 kg·cm 以上选。常见做法是腿部用 MG996R 这类 9.4 kg·cm4.8V级别的舵机髋关节用同型号或者稍大一号的 MG995。重量上 18 个这种舵机加起来接近 1 kg结构件的承载和重心设计要提前算好。2.2 三自由度腿结构与 3D 打印结构件每条腿的 3 个自由度从身体向外排列髋关节舵机横向安装输出轴垂直于地面大腿舵机纵向安装输出轴平行于地面小腿舵机安装在大腿末端输出轴同样平行于地面。这样布置的好处是正逆运动学模型简单髋关节旋转只影响腿部平面方向大腿和小腿的转角只影响足端在腿部平面内的位置。结构件我的建议是用 3D 打印 PLA 或者 PETG壁厚 3 mm填充 40% 以上。PLA 刚性够但脆受力部位要加圆角PETG 韧性好但打印温度高层间结合力更强。舵机安装孔位要配合舵机自带的十字形输出臂用内六角螺丝加尼龙垫圈固定舵机臂和结构件之间不要用胶水粘连因为调试阶段拆装频率很高。3D 打印件的尺寸公差要控制在 0.3 mm 以内如果舵机安装孔紧了用锉刀修不要硬敲进去否则舵机壳体会变形齿轮阻力变大最终表现为待机状态持续发热。2.3 供电设计18 路舵机的电流冲击是最大坑点18 个舵机同时动作瞬时电流可以达到 5 A 以上堵转时甚至能到 10 A。如果直接用 STM32 开发板的 5V 引脚供电板上 LDO 和 USB 保护电路瞬间烧毁。六足供电架构常见做法是分两路舵机电源2S 锂电池7.4V或 5V/8A 以上的舵机专用电源经过大电流 BEC 降压到 6V给舵机供电逻辑电源同一个电池经过另一路 BEC 降压到 5V给 STM32、IMU、超声波传感器供电。这里有一个关键点两路电多路转换器必须共地也就是 GND 互联否则舵机 PWM 信号没有参考地舵机会在启动瞬间随机抽动严重时信号引脚被灌入反向电压烧坏。另外舵机电源输入端要并联一个大容量电容比如 25V/1000 μF 的电解电容和 0.1 μF 瓷片电容电解电容负责吸收舵机启动时的电压跌落瓷片电容滤除高频毛刺。我遇到过舵机启动瞬间 MCU 复位的现象最后查下来就是电源跌落导致加电容后解决。2.4 STM32 选型和引脚分配六足项目的 STM32 选型看两个硬件资源定时器 PWM 通道数量和 I2C/串口数量。18 路舵机如果全部由 MCU 直接产生 PWM需要 18 个通道普通 F103 系列只有 12 个 PWM 输出同一定时器通道不够用。所以实际项目里一般有两种做法一种是用 STM32F407 这类高级定时器更多的型号另一种是 STM32F103 PCA9685 舵机驱动板扩展PCA9685 可以提供 16 路 PWM两片就覆盖 18 路。我比较推荐后者因为 PCA9685 的 I2C 接口只需要两根线同时它自带 1 kHz 到 1.6 kHz 的 PWM 频率正好匹配舵机 50 Hz 的更新周期附近的需求。后面的实现章节会具体展开。3. 运动学与步态让六足先站得住再走得稳3.1 坐标系统与腿部模型的抽象把六足的每条腿抽象成一个三连杆机械臂髋关节转角 记为 θ1大腿转角 记为 θ2小腿转角 记为 θ3。定义腿的伸展方向为 X 轴正方向身体侧向为 Y 轴竖直向上为 Z 轴。足端位置可以由腿根部的坐标出发通过几何关系计算出来。对于每条腿我们需要求解逆运动学给定足端目标位置 (x, y, z)反算出三个关节角。这个计算是步态规划的基础因为步态本质上就是规划足端的轨迹再由逆运动学折算到舵机角度。3.2 逆运动学公式推导与代码实现逆运动学推导的关键是几何拆分。髋关节角 θ1 直接由足端在水平面的方位角决定θ1 atan2(y, x)把足端位置转到腿平面内大腿与小腿构成的平面中大臂长度 L1大腿连杆、小臂长度 L2小腿连杆已知。腿平面内的水平距离 r 和垂直高度 z 满足r sqrt(x² y²) - L0其中 L0 是髋关节到腿根部的固定偏心距。然后按平面两连杆模型求解 θ2 和 θ3。cosθ3 (r² z² - L1² - L2²) / (2·L1·L2)θ3 acos(夹紧范围θ2 atan2(z, r) - atan2(L2·sinθ3, L1 L2·cosθ3)。用 C 语言实现这个逆运动学求解函数typedef struct { float l0; // 髋关节偏心距 float l1; // 大腿长度 float l2; // 小腿长度 float servo_offset[3]; // 舵机角度偏移校准值 } LegGeometry; void leg_ik(LegGeometry *leg, float x, float y, float z, float *theta1, float *theta2, float *theta3) { // 髋关节角足端水平方向与身体坐标系的夹角 *theta1 atan2f(y, x); // 将足端位置折算到腿平面内 float r_plane sqrtf(x * x y * y) - leg-l0; float z_plane z; // 平面两连杆逆运动学余弦定理 float cos_t3 (r_plane * r_plane z_plane * z_plane - leg-l1 * leg-l1 - leg-l2 * leg-l2) / (2.0f * leg-l1 * leg-l2); if (cos_t3 1.0f) cos_t3 1.0f; if (cos_t3 -1.0f) cos_t3 -1.0f; *theta3 acosf(cos_t3); float beta atan2f(z_plane, r_plane); float alpha atan2f(leg-l2 * sinf(*theta3), leg-l1 leg-l2 * cosf(*theta3)); *theta2 beta - alpha; // 转成舵机安装角度角度制并叠加机械零位偏移 *theta1 *theta1 * 180.0f / M_PI leg-servo_offset[0]; *theta2 *theta2 * 180.0f / M_PI leg-servo_offset[1]; *theta3 *theta3 * 180.0f / M_PI leg-servo_offset[2]; }这段代码里的atan2f处理了 x 为负时象限角的问题acosf的输入范围需要截断否则浮点误差会让结果变成 NaN舵机角度就会乱跳。servo_offset是安装时每个舵机的机械零位补偿值因为舵机输出轴上的舵机臂很难装到完全标准的 90°这个偏移必须在整机装配后逐一测量并写死。注意逆运动学算出的角度是按照四象限的而舵机在安装时零点方向可能不一致。如果 θ1 的范围是 -45° 到 45°而你的舵机安装成 0 到 180°需要在映射阶段做线性变换。3.3 三角步态与抬腿轨迹规划最常见的六足步态是三角步态tripod gait将 6 条腿分成两组分别是 L1、R2、L3 和 R1、L2、R3。行走时一组腿抬起并向前摆动另一组腿着地并向后推动身体两组交替进行。这种步态速度快、控制模型简单适合平地行走缺点是在粗糙地面上稳定性略差因为只有 3 条腿支撑。对于毕设级别的项目三角步态已足够。摆动腿的足端轨迹建议采用摆线轨迹或者梯形速度轨迹。摆线轨迹的数学形式是在步态周期的摆动相中足端从后极限位置抬起到最高点再落到前极限位置水平和垂直方向的运动是同相的。用代码生成 20 个插值点void swing_trajectory(float start_x, float start_y, float start_z, float end_x, float end_y, float end_z, float step_height, int num_points, float *traj_x, float *traj_y, float *traj_z) { for (int i 0; i num_points; i) { float t (float)i / num_points; float phase t * 2.0f * M_PI; // 水平方向线性插值 traj_x[i] start_x (end_x - start_x) * t; traj_y[i] start_y (end_y - start_y) * t; // 垂直方向半周期正弦保证起点和终点高度都为 0 traj_z[i] start_z step_height * sinf(phase / 2.0f); } }之所以用半正弦而不是线段是因为半正弦轨迹保证了起点和终点的垂直速度为零足端落地瞬间冲击小不会让机身震动和舵机过流。step_height 是抬腿高度6 自由度六足建议 30~50 mm地面越复杂取越大但过大会让摆动腿的重心偏移影响机身稳定性。3.4 步态参数配置表与调试入口把步态参数集中到一个结构体里方便在线调参参数典型值范围作用step_duration300~600 ms单步摆动时长越短走得越快但舵机负载越大step_height20~50 mm摆动腿离地高度step_length30~70 mm步距越大速度越快但容易失稳body_height60~100 mm机身离地高度越低越稳但越容易刮底phase_offset0.5两组腿的相位差固定为半周期在线调参后接下来要看舵机角度计算是否正确。先让机器人悬挂起来万向支架或者几本书垫着单独操控髋关节、大腿、小腿观察足端是否按预期方向移动。如果 x 坐标变大时足端反而向内靠近说明某个舵机角度方向定义反了很可能是在逆运动学代码里 θ2 正负号反了。这时候把该关节的角度乘以 -1 即可而不是去改舵机接线。4. STM32 工程实现PWM 生成、串口调参与实时调度4.1 CubeMX 配置定时器、波特率与引脚分配方案在 STM32CubeMX 里如果采用 STM32F103 PCA9685 的方案MCU 需要的定时器资源大幅减少。配置一个定时器用来做舵机刷新节拍用 I2C1 连接 PCA9685用 USART1 连接蓝牙或 USB 转串口调试用 I2C2 或软件 I2C 连接 MPU6050。我这里以 F103RCT6 为例它自带 256 KB Flash、48 KB RAM跑六足控制和基础传感器融合都够如果你要加摄像头做视觉避障建议换 STM32F429 或者干脆用树莓派做上层、STM32 做运动控制。PCA9685 的 PWM 频率设置为 50 Hz也就是周期 20 ms。PCA9685 的输出脉宽范围对应的寄存器值是 0 到 409550 Hz 下 0~180° 角度映射到脉宽大约 500 μs 到 2500 μs对应寄存器值从 102 到 512。舵机角度和脉宽的关系线性映射足够用因为非线性的死区主要集中在两端日常行走范围在 30° 到 150° 之间。映射代码// PCA9685 舵机角度 - 占空比寄存器值 uint16_t angle_to_pwm(float angle_deg) { // 限幅到 0~180 if (angle_deg 0.0f) angle_deg 0.0f; if (angle_deg 180.0f) angle_deg 180.0f; // 500us 到 2500us50Hz 下对应 102 ~ 5124096 步 float pulse_us 500.0f (angle_deg / 180.0f) * 2000.0f; return (uint16_t)(pulse_us * 4096.0f / 20000.0f); }4.2 STM32 端舵机控制与 PCA9685 读写封装PCA9685 的 I2C 写寄存器比较简单每个通道有 4 个寄存器分别存 TURN_ON 的低字节、高字节TURN_OFF 的低字节、高字节。设置输出脉宽时把 ON 时间设为 0OFF 时间设为angle_to_pwm的返回值。批量更新 18 路舵机的常见做法是先写一个数组缓存所有通道的目标角度然后在每个控制周期统一写入避免在更新过程中某条腿先动、其他腿还没动造成机身扭曲。4.3 USART 串口调参协议与中断解析串口调试是调试六足最有效的入口。很多 STM32 项目里调试参数靠 「重新修改源码 → 烧录 → 观察」 的循环这一步笨且浪费时间。六足姿态参数反复调是常态所以我在项目里会内置一个简单串口协议。协议格式是CMD:P1value,P2value\n例如STEP:HEIGHT40,LEN60,SPEED200\n表示设置抬腿高度 40 mm、步距 60 mm、单步时长 200 ms。解析代码用状态机接收一行字符串// USART1 中断接收实现指令解析 void USART1_IRQHandler(void) { uint8_t byte; if (LL_USART_IsActiveFlag_RXNE(USART1)) { byte LL_USART_ReceiveData8(USART1); static uint8_t buf[64]; static uint8_t idx 0; if (byte \n || idx sizeof(buf) - 1) { buf[idx] \0; parse_command((char *)buf); // 解析命令 idx 0; } else { buf[idx] byte; } } }中断函数里不要做复杂的浮点运算或者字形打印只做「收字节 暂存 遇到换行置标志」主循环里去执行解析。否则串口中断被舵机刷新逻辑打断时数据容易丢。parse_command内部用strstr匹配关键词再配合atoi或atof取出数值。调试时用串口工具或者自己写一个 Python 脚本来发指令再配合 MPU6050 的回传数据判断机身姿态这就是一套简易的遥测/遥控调试系统。4.4 调度时序与实时性18 路舵机的更新频率不用太高50 Hz 的刷新率对舵机响应基本是上限再快舵机内部电路也跟不上了。步态计算频率可以做到 100 Hz也就是每 10 ms 计算一次所有腿的目标位置并写入 PCA9685。这样 MCU 负载很轻剩余时间全部留给传感器读取和决策逻辑。任务结构用简单的定时器中断 主循环或者 FreeRTOS 都行。裸机实现时控制周期用定时器中断标记主循环检查标志防止舵机角度更新和步态计算发生竞态。5. 让六足拥有感知IMU、超声波与简单避障决策5.1 MPU6050 姿态读取与零漂处理六足在行走时身体会周期性倾斜特别是在转向或单步切换的瞬间。如果不做姿态反馈每条腿的轨迹纯粹是开环的一旦地面不平机器人会越走越偏最终摔倒。所以整套系统会配一个 MPU6050 六轴 IMU陀螺仪和三轴加速度计融合输出俯仰角和横滚角。常见做法是直接使用 DMP数字运动处理器库读取四元数然后转换为欧拉角这样可以避免自己写卡尔曼滤波的调参过程。注意MPU6050 的原始加速度计数据噪声很大直接用于角度控制会造成抖动。DMP 模式自带低通滤波姿态角输出相对平滑推荐默认打开。5.2 超声波传感器布局与测距实现避障传感器我用的是 HC-SR04 超声波装在机器人头部位置向下倾斜 15° 左右这样既能探测正前方障碍物也能部分探测到较低的小障碍物。HC-SR04 的触发信号是 10 μs 以上的低高电平脉冲STM32 用 GPIO 模拟时序即可不需要专门的 PWM 外设// HC-SR04 单次测距 float ultrasonic_distance(void) { uint32_t tick_start, tick_end, duration; // 拉高 TRIG 10us HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET); delay_us(10); HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET); // 等待 ECHO 高电平 while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) GPIO_PIN_RESET); tick_start DWT-CYCCNT; while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) GPIO_PIN_SET); tick_end DWT-CYCCNT; duration (tick_end - tick_start) / (SystemCoreClock / 1000000); return (float)duration * 0.034f / 2.0f; // 声速 340m/s 折算成距离(cm) }这段代码里用 DWT 计数做微秒延时精度比普通循环高很多如果 MCU 主频是 72 MHzDWT-CYCCNT每秒累计 7200 万次所以结束开始再除以 72 就是微秒数。注意 HC-SR04 的有效测量范围是 2 cm 到 400 cm小于 2 cm 时输出不稳定遇到这种情况直接按“无有效数据”处理不要作为障碍物距离使用。5.3 感知融合与状态机决策有了 IMU 姿态和超声波距离决策逻辑可以做成一个简单的状态机。状态包括直行、左转、右转、原地调整、暂停。直行时超声波距离大于 30 cm距离小于 20 cm 时需要避障。避障这里有一个关键策略不要每次都朝同一个方向转否则遇到墙角会陷入反复横跳。加一个计数连续 3 次前方有障碍时卸掉前行的倾向改为原地 180° 掉头或者反向后退一步再转向。“融合”这两个字在这里不需要太玄乎IMU 负责行走时的姿态稳定性超声波负责环境感知行为决策只管突发事件。三者的优先级从高到低是避障 姿态调整 步态。比如正在执行步态规划突然测到前方 5 cm 有障碍必须立刻终止当前步态周期先把各腿收到安全位置再做避障动作。5.4 姿态补偿的轻量实现如果要让六足在不太平的地面走得稳需要把 IMU 的横滚角补偿到步态里。常见做法是把机身目标姿态映射到每条支撑腿的足端高度偏移当机身右倾时降低右侧腿的高度或抬高左侧腿的高度。这个补偿量可以简单用pitch * scale来叠加。scale 取多大的值取决于机身到足端的杠杆比经验上机身向左倾斜 1°左侧支撑腿足端就抬高 1.5 到 2 mm。补偿频率跟随步态控制周期10 ms 更新一次动态效果基本够用。如果要做更高精度的力控或主动平衡就需要在每条腿上装压力传感器或电流传感器那是另一个量级的工程了。6. 复现与验证三步确认你的六足可以交付6.1 舵机归零检查这一步不用烧录代码用 PCA9685 的自带测试模式或者 STM32 的串口手动指令把 18 个舵机全部发到 90°也就是脉宽 1500 μs。观察两条腿对应关节是否处于同一平面的中间位置。如果某条腿明显偏转记录偏差角度并更新到servo_offset。6.2 支撑稳定性验证让机器人站在平地上从侧面观察机身是否水平。不正常时优先检查电池位置电池应该放正并贴在底盘的几何中心附近。若机身左右不平调整相关腿的servo_offset不要强行调结构件的垫片因为垫片会引入额外的机械应力和扭矩。6.3 动态越障的验证方法设置一组步距 40 mm、抬腿高度 35 mm 的步态参数在地面放一本 A4 纸叠成的 1 cm 高障碍观察六足跨过时的机身姿态变化。如果越障瞬间出现严重晃动优先减小步距再微调抬腿高度。常见问题是抬腿高度与步距不匹配腿抬得太高但步距小机器人会原地“踏步”而前进缓慢步距太大且抬腿低小腿会刮到障碍物。开环验证全部通过后再打开 IMU 补偿避障开关把机器人的自主行走能力作为最终验证。整机运行 10 分钟以上舵机温度、电池电压下降趋势、串口回传的姿态角波动区间都要在可接受范围内。这就是一次完整的交付闭环——从舵机归零、静态支撑、动态越障到带传感器的自主巡逻一步步推进尽量避免到最后一步才发现机械结构有问题。本文还有配套的精品资源点击获取