当前位置: 首页 > news >正文

从玩具舵机到机械臂:手把手教你用STM32F103+CubeMX配置PWM,驱动SG90和MG995搭建第一个机器人关节

从玩具舵机到机械臂:STM32F103驱动SG90与MG995构建机器人关节全指南

在创客和机器人爱好者的世界里,舵机是最基础也最迷人的执行元件之一。想象一下,通过几行代码就能精确控制一个机械部件的角度位置,这种将数字信号转化为物理运动的魔法,正是构建自动化装置的第一步。无论是制作会挥手的机器人、自动追踪阳光的太阳能板,还是简易的机械臂原型,舵机都能提供简单可靠的解决方案。

本文将带你从零开始,使用STM32F103微控制器和CubeMX配置工具,构建一个完整的机器人关节系统。不同于单纯的理论讲解,我们会聚焦于实际应用场景,比较SG90和MG995这两款常见舵机的性能差异,设计可3D打印的机械结构,并最终实现一个能往复摆动的关节demo。这个项目特别适合嵌入式初学者和机器人爱好者,你不仅能学到PWM信号生成的原理,还能获得从电路连接到机械组装的完整实践经验。

1. 硬件选型与准备工作

1.1 认识我们的主角:SG90与MG995舵机

舵机本质上是一种带有反馈控制的位置伺服电机,它通过接收PWM信号来精确控制输出轴的角度位置。市场上最常见的两种舵机是SG90和MG995,它们虽然工作原理相同,但在性能和应用场景上有着显著差异。

让我们通过一个对比表格来直观了解这两款舵机的关键参数:

参数SG90MG995
尺寸23×12.2×29mm40.7×19.7×42.9mm
重量9克66.2克
工作电压4.8-7.2V3.0-7.2V
无负载速度0.3秒/60度0.17秒/60度(4.8V)
扭矩1.5kg/cm13kg/cm
价格区间10-20元40-60元

从表格可以看出,MG995在扭矩和速度上明显优于SG90,但体积和重量也更大。SG90更适合小型、轻负载的应用,比如机器人手指或小型摄像头云台;而MG995则适用于需要更大力量的场景,如机器人手臂关节或重型转向机构。

提示:虽然MG995标称工作电压可低至3V,但实际测试中3V电压几乎无法驱动舵机运转,建议至少使用4.8V以上电源。

1.2 STM32F103开发板选择与周边配件

对于这个项目,我们推荐使用STM32F103C8T6最小系统板(俗称"蓝莓板"),它具有以下优势:

  • 价格低廉(通常20-30元)
  • 内置STM32F103C8T6芯片,72MHz主频,性能足够
  • 具备多个定时器,可生成多路PWM信号
  • 支持通过ST-Link进行程序烧录和调试

除了开发板,你还需要准备:

  • 5V电源(可以是USB电源或专用电源模块)
  • 杜邦线若干(建议使用不同颜色区分功能)
  • 万用表(用于调试时检查电压和连接)
  • 可选:示波器(用于观察PWM波形)

2. CubeMX配置与PWM生成

2.1 STM32CubeMX基础配置

STM32CubeMX是ST官方提供的图形化配置工具,能大幅简化外设初始化过程。以下是配置步骤:

  1. 打开CubeMX,创建新工程,选择对应型号(STM32F103C8)
  2. 在"Pinout & Configuration"选项卡中配置系统时钟:
    • 选择HSE(外部高速时钟)作为时钟源
    • 设置系统时钟为72MHz
  3. 配置调试接口(通常为SWD):
    • 在"System Core"→"SYS"中,选择"Serial Wire"调试模式

2.2 定时器PWM配置详解

舵机需要50Hz(周期20ms)的PWM信号,我们可以使用STM32的通用定时器(如TIM2)来生成这种信号。以下是具体配置步骤:

  1. 在CubeMX中激活TIM2:

    • 在"Timers"→"TIM2"中,将时钟源设为"Internal Clock"
    • 将通道1设为"PWM Generation CH1"
  2. 配置定时器参数:

    • Prescaler(预分频器):71(72MHz/(71+1)=1MHz)
    • Counter Period(自动重装载值):19999(1MHz/20000=50Hz)
    • Pulse(初始脉冲宽度):1500(对应1.5ms,舵机中位)
  3. 生成代码:

    • 在"Project Manager"中设置好工程名称和路径
    • 选择适合的IDE(如MDK-ARM或STM32CubeIDE)
    • 点击"Generate Code"创建工程

生成的初始化代码会自动配置好定时器和GPIO,我们只需要在应用代码中修改占空比即可控制舵机角度。

2.3 PWM信号与舵机角度关系

舵机角度由PWM脉冲的高电平持续时间决定,典型关系如下:

0.5ms高电平 —— 0度位置 1.0ms高电平 —— 45度位置 1.5ms高电平 —— 90度位置(中位) 2.0ms高电平 —— 135度位置 2.5ms高电平 —— 180度位置

在代码中,我们可以使用以下函数设置角度:

void Set_Servo_Angle(TIM_HandleTypeDef *htim, uint32_t Channel, float angle) { // 将角度转换为对应的脉冲宽度 // 假设angle范围是0-180度 uint32_t pulse = 500 + (angle / 180.0) * 2000; // 500-2500us __HAL_TIM_SET_COMPARE(htim, Channel, pulse); }

3. 机械结构设计与组装

3.1 3D打印关节设计要点

一个实用的机器人关节需要考虑以下几个机械因素:

  • 固定方式:舵机需要稳固地固定在基座上,避免工作时晃动
  • 力传递:输出轴与被驱动部件的连接要牢固,避免打滑
  • 负载平衡:确保舵机不会承受超出其能力的侧向力

对于SG90舵机,可以使用以下简单的支架设计(OpenSCAD代码):

// SG90舵机支架 module sg90_mount() { difference() { // 底座 cube([40, 20, 2], center=true); // 舵机固定孔 translate([12.5, 0, 0]) cylinder(d=2.5, h=5, center=true); translate([-12.5, 0, 0]) cylinder(d=2.5, h=5, center=true); // 舵机主体空间 cube([23, 12.2, 10], center=true); } // 侧边支撑 translate([0, 10, 5]) cube([30, 2, 10], center=true); translate([0, -10, 5]) cube([30, 2, 10], center=true); }

3.2 无3D打印机的替代方案

如果没有3D打印机,可以使用以下材料手工制作支架:

  1. 材料选择

    • 亚克力板(易于切割和钻孔)
    • 铝型材(强度高,可组合)
    • 木板(容易加工但耐久性较差)
  2. 制作步骤

    • 测量舵机尺寸,设计简单的L型支架
    • 使用手锯或激光切割机切割材料
    • 钻孔固定舵机和基座
    • 使用螺丝和螺母组装

注意:手工制作时务必确保所有连接牢固,舵机工作时会产生振动,松动的连接件可能导致项目失败甚至损坏设备。

4. 软件实现与调试技巧

4.1 完整控制代码实现

基于HAL库的完整控制代码如下,实现了舵机在0-180度之间往复运动:

#include "main.h" #include "stm32f1xx_hal.h" TIM_HandleTypeDef htim2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); void Set_Servo_Angle(TIM_HandleTypeDef *htim, uint32_t Channel, float angle) { uint32_t pulse = 500 + (angle / 180.0) * 2000; // 500-2500us __HAL_TIM_SET_COMPARE(htim, Channel, pulse); } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); float angle = 0; int direction = 1; // 1 for increasing, -1 for decreasing while (1) { Set_Servo_Angle(&htim2, TIM_CHANNEL_1, angle); HAL_Delay(20); // 给舵机时间到达指定位置 angle += direction * 5; // 每次改变5度 if (angle >= 180) direction = -1; if (angle <= 0) direction = 1; } } // 此处省略CubeMX生成的初始化代码...

4.2 常见问题与调试方法

在实际项目中,你可能会遇到以下问题及解决方案:

  1. 舵机不响应

    • 检查电源:确保5V电源能提供足够电流(SG90约需100-300mA)
    • 检查接线:确认信号线连接正确,红线接5V,黑/棕线接GND
    • 用示波器检查PWM信号是否正常
  2. 舵机抖动或发热严重

    • 可能是机械负载过大,超过舵机额定扭矩
    • 检查PWM信号是否稳定,避免频繁改变角度指令
    • 确保舵机有足够的冷却时间
  3. 角度不准确

    • 不同舵机可能存在个体差异,需要校准
    • 尝试调整PWM脉冲宽度范围(有时0.6ms-2.4ms效果更好)
    • 检查电源电压是否稳定,电压波动会影响舵机性能
// 舵机校准代码示例 void Servo_Calibration(TIM_HandleTypeDef *htim, uint32_t Channel) { // 找到0度和180度对应的精确脉冲宽度 for (int pulse = 500; pulse <= 2500; pulse += 10) { __HAL_TIM_SET_COMPARE(htim, Channel, pulse); HAL_Delay(1000); // 观察舵机位置 } }

5. 项目扩展与进阶应用

5.1 多自由度机械臂设计

掌握了单个关节的控制后,可以尝试构建更复杂的多自由度系统。例如,一个三自由度机械臂需要:

  1. 底座旋转关节:控制整个机械臂的水平旋转
  2. 肩关节:控制大臂的上下运动
  3. 肘关节:控制小臂的上下运动

每个关节需要一个独立的舵机,可以通过STM32的多个定时器通道或一个定时器的不同通道来控制。

// 多舵机控制示例 #define BASE_SERVO TIM_CHANNEL_1 #define SHOULDER_SERVO TIM_CHANNEL_2 #define ELBOW_SERVO TIM_CHANNEL_3 void Control_Robot_Arm(float base_angle, float shoulder_angle, float elbow_angle) { Set_Servo_Angle(&htim2, BASE_SERVO, base_angle); Set_Servo_Angle(&htim2, SHOULDER_SERVO, shoulder_angle); Set_Servo_Angle(&htim2, ELBOW_SERVO, elbow_angle); }

5.2 加入传感器反馈

为了构建更智能的系统,可以考虑加入各种传感器:

  1. 电位器反馈:测量关节实际位置,实现闭环控制
  2. 力传感器:检测机械臂是否碰到障碍物
  3. 视觉传感器:使用摄像头实现目标跟踪
// 使用ADC读取电位器值示例 void Read_Potentiometer(void) { HAL_ADC_Start(&hadc1); if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { uint32_t adc_value = HAL_ADC_GetValue(&hadc1); // 将ADC值转换为角度(0-180) float angle = (adc_value / 4095.0) * 180.0; // 使用角度值进行反馈控制... } HAL_ADC_Stop(&hadc1); }

5.3 上位机控制接口

通过串口或蓝牙与电脑/手机通信,可以实现远程控制:

  1. 串口通信协议设计

    • 定义简单的文本协议,如"SERVO1 90"设置第一个舵机到90度
    • 或者使用二进制协议提高传输效率
  2. Python控制界面示例

import serial import time ser = serial.Serial('COM3', 115200) # 根据实际情况修改端口 def set_angle(servo_id, angle): command = f"SERVO{servo_id} {angle}\n" ser.write(command.encode()) # 示例:让舵机1从0度扫到180度 for angle in range(0, 181, 5): set_angle(1, angle) time.sleep(0.1)

在实际项目中,我发现MG995虽然扭矩大,但在快速运动时会产生明显的电流冲击,容易导致电源电压跌落。解决方法是:

  1. 使用大容量电容(如1000μF)并联在电源端
  2. 为每个舵机添加独立的稳压电路
  3. 在软件中实现平滑的运动曲线,避免突然的角度变化
http://www.jsqmd.com/news/937285/

相关文章:

  • 保姆级避坑指南:用Anaconda3和PyTorch 1.12.0在Windows上搞定NeRF-PyTorch环境(附清华源)
  • 天津建材商户实测:黑退六角管2026选型避坑指南 - 品牌优选官
  • Arduino继电器控制入门:用旋钮改造传统雪球玩具
  • 告别烧录失败!用ESPFlashDownloadTool_v3.6.3给NodeMCU刷固件的保姆级避坑指南
  • AI动态简报之商业洞察篇(2026.06.02)
  • gibMacOS:跨平台下载macOS系统镜像的专业解决方案
  • 成都束美全屋定制靠谱吗?2026企业资质/报价/口碑/售后深度分析 - 速递信息
  • AI与大数据融合实践:从架构设计到场景落地的全链路指南
  • 学术落地新思路|paperxie 依托 DS 模型拆解本科毕业论文全链路 AI 落地逻辑
  • d2s-editor终极指南:安全修改暗黑破坏神2存档的完整教程
  • 新手必看:用Keil和Proteus 8.9给AT89C51单片机做个简易秒表(附完整代码和仿真文件)
  • UE4材质进阶:别再直接调UV了!手把手教你正确控制法线贴图强度(附节点连线图)
  • LLM辅助特征工程,AutoML调度GPU集群,MLOps平台自动埋点——AI工具整合的7层能力跃迁,你卡在哪一层?
  • 传统喝水越多越好,编写程序,结合气温运动量,肾功能数据,计算个人每日精准饮水量,预警饮水过量。
  • 从分步式创作逻辑拆解:paperxie 毕业论文模块如何贴合高校规范解决论文写作卡点
  • 从摄像头模组到SoC:MIPI-CSI2 DPHY信号完整性实战调优指南
  • 智慧职教学习助手:告别手动刷课的低效时代
  • Web工程化命题,拒绝页面仔
  • python中的浅拷贝和深拷贝
  • 向量空间JBoltAI:从产品痛点看AI怎么解
  • 智能音箱DIY改造:移植SONOS模块到传统户外音箱
  • 2026 深圳钻石回收实测榜单|五大正规机构真实测评! - 合扬奢侈品交易中心
  • 终极免费Mac鼠标指针定制指南:如何告别单调光标的完整解决方案
  • 1200kV/120kJ冲击发生器的结构配置
  • 2026 儿童读书会体系哪家好?TOP5 标杆品牌实测,省心省力选对课 - 资讯快报
  • 从特斯拉到理想:拆解主流车型ADAS摄像头参数,看车企的‘视觉方案’到底怎么选
  • 如何用Boss Show Time插件掌握招聘时效性:求职者的智能时间管理工具
  • 基于Arduino与PCA9685的智能LED灯光系统设计与实现
  • 大模型的典型应用场景
  • 不止于点击高亮:用Unity的QuickOutline插件,5分钟搞定AR/VR中的物体交互反馈