1. 项目背景与核心需求
在机器人开发、航模制作等嵌入式控制领域,舵机是最常用的执行机构之一。无论是调试单个舵机的响应特性,还是测试多路舵机的协同工作,一个可靠的舵机测试仪都是开发者的必备工具。市面上的成品测试仪往往功能单一或价格昂贵,而基于STM32F103C8T6的自制方案则完美平衡了灵活性与成本。
这个项目之所以选择STM32F103C8T6作为主控,主要基于三个核心考量:
- 丰富的外设资源:该芯片具有多达7个定时器,其中TIM1/TIM2/TIM3/TIM4都支持PWM输出,非常适合多路舵机控制
- 性价比优势:C8T6作为经典款Cortex-M3内核MCU,市场价格通常在10元以内
- 成熟的生态:标准库和HAL库资料丰富,社区支持完善
提示:虽然STM32F103系列已推出多年,但其稳定的性能和广泛的应用案例,使其依然是入门级32位MCU的首选。特别是C8T6这个64脚封装版本,在保持足够I/O的同时,体积也非常适合嵌入式设备。
2. 硬件准备与电路设计
2.1 核心器件选型
完整的物料清单如下表所示,其中标*的为可选配件:
| 类别 | 型号/参数 | 数量 | 备注 |
|---|---|---|---|
| 主控 | STM32F103C8T6 | 1 | 建议选择蓝色开发板 |
| 下载器 | ST-LINK V2 | 1 | 也可用USB转TTL+串口下载 |
| 显示模块 | 0.96寸OLED(I2C) | 1 | 4针脚版本 |
| 舵机接口 | 3P杜邦插座 | 4-8 | 根据需求确定 |
| 电源模块 | AMS1117-5.0 | 1 | 如需外部供电 |
| 按键 | 轻触开关 | 3-5 | 菜单/参数调节用 |
| *调试工具 | 逻辑分析仪 | 1 | 用于PWM波形验证 |
2.2 关键电路设计要点
电源部分需要特别注意舵机的供电特性:
- 开发板USB供电时,最大只能提供500mA电流,仅适合测试1-2个小扭矩舵机
- 多路舵机或大扭矩舵机(如MG995)必须使用独立电源,建议方案:
- 外接5V/2A以上电源
- 通过AMS1117降压至3.3V给MCU供电
- 电源输入端加1000μF电容滤波
PWM输出接口设计建议:
// 推荐使用的定时器通道配置 TIM1_CH1 -> PA8 // 通道1 TIM2_CH1 -> PA0 // 通道2 TIM3_CH1 -> PA6 // 通道3 TIM4_CH1 -> PB6 // 通道4注意:SG90这类微型舵机工作电流约100-200mA,而MG995在堵转时可能达到1.2A,务必根据舵机型号设计合适的电源电路,否则可能导致MCU复位或USB端口保护。
3. 软件开发环境搭建
3.1 工具链配置
推荐使用以下开发环境组合:
- Keil MDK-ARM V5(需安装Device Family Pack)
- STM32CubeMX V6.5(用于外设初始化)
- ST-LINK Utility(用于程序下载)
对于习惯开源工具链的开发者,也可以选择:
- 编译器:Arm GNU Toolchain
- 构建系统:Makefile
- 调试工具:OpenOCD + GDB
3.2 工程创建步骤
在CubeMX中完成基础配置:
- 时钟树:设置外部8MHz晶振,系统时钟72MHz
- 调试接口:Serial Wire(SWD)
- 定时器:TIM1/2/3/4选择PWM Generation模式
- GPIO:配置用户按键和OLED的I2C接口
关键参数计算示例(以50Hz舵机信号为例):
定时器时钟 = 72MHz 预分频值(PSC) = 71 // 72MHz/(71+1) = 1MHz 自动重载值(ARR) = 19999 // 1MHz/(19999+1) = 50Hz 脉宽范围 = 500-2500 // 对应0.5ms-2.5ms生成代码后,需要手动添加的功能模块:
- OLED显示驱动(SSD1306)
- 旋转编码器或按键扫描逻辑
- 菜单界面管理系统
4. PWM信号生成原理与实现
4.1 舵机控制协议解析
标准舵机控制采用周期20ms(50Hz)的PWM信号,其中高电平脉宽与角度对应关系如下:
| 脉宽(ms) | 舵机角度 |
|---|---|
| 0.5 | 0° |
| 1.0 | 45° |
| 1.5 | 90° |
| 2.0 | 135° |
| 2.5 | 180° |
在代码中的具体实现:
void SetServoAngle(TIM_HandleTypeDef *htim, uint32_t Channel, float angle) { // 将角度转换为CCR值 uint32_t pulse = 500 + (angle / 180.0) * 2000; // 500-2500us __HAL_TIM_SET_COMPARE(htim, Channel, pulse); }4.2 多路PWM同步输出技巧
当需要控制多路舵机时,建议采用以下优化方案:
- 使用TIM1的高级定时器功能,可以同步更新所有通道
- 通过DMA传输CCR值,减少CPU干预
- 关键配置代码示例:
// TIM1初始化片段 htim1.Instance = TIM1; htim1.Init.Prescaler = 71; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 19999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;5. 用户界面设计与功能实现
5.1 OLED菜单系统
推荐采用分层菜单结构:
主界面显示:
- 当前通道选择
- PWM脉宽数值
- 对应角度值
- 输出使能状态
参数设置菜单:
- 通道选择(1-4)
- 脉宽微调(±10us)
- 角度预设(0°/45°/90°/135°/180°)
- 信号开关
5.2 按键控制逻辑
典型的3按键方案实现:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t last_tick = 0; if(HAL_GetTick() - last_tick < 100) return; if(GPIO_Pin == KEY_UP_Pin){ current_pulse += 10; // 脉宽+10us } else if(GPIO_Pin == KEY_DOWN_Pin){ current_pulse -= 10; // 脉宽-10us } else if(GPIO_Pin == KEY_ENTER_Pin){ servo_enable = !servo_enable; // 切换输出状态 } last_tick = HAL_GetTick(); }6. 系统调试与性能优化
6.1 常见问题排查
舵机无反应:
- 检查电源电压是否≥4.8V
- 用示波器测量PWM信号是否正常
- 确认信号地线与电源地已连接
舵机抖动:
- 增加电源滤波电容
- 检查PWM周期是否稳定50Hz
- 避免机械结构卡死
OLED显示异常:
- 确认I2C地址(通常0x78或0x7A)
- 检查上拉电阻(4.7kΩ)
- 降低I2C时钟速度(≤400kHz)
6.2 进阶功能扩展
增加蓝牙控制(JDY-31模块):
- 通过串口接收手机APP指令
- 实现无线参数调整
添加舵机扫描功能:
- 自动循环0°-180°
- 记录舵机响应曲线
支持SBUS协议:
- 解析富斯接收机信号
- 实现遥控器直接控制
我在实际制作中发现,给每个PWM输出通道增加LED指示灯非常实用,可以直观显示信号输出状态。另外,使用热熔胶固定杜邦插座能有效防止测试时接触不良。对于需要频繁更换舵机的场景,建议改用EC5或XT30这类航模插头,比杜邦接口更可靠。