1. SG90舵机基础与PWM控制原理SG90舵机是创客和嵌入式开发者最常用的微型舵机之一价格亲民但性能可靠。我第一次接触它是在做一个智能垃圾桶项目需要用它来控制桶盖的开合。这种舵机内部包含直流电机、减速齿轮组、控制电路和电位器通过电位器反馈实现闭环控制。舵机通常有三根线棕色线接地GND红色线电源正极4.8-6V黄色线PWM信号输入PWM控制是舵机的核心。我实测过SG90对PWM信号的要求是频率50Hz周期20ms脉宽范围0.5ms-2.5ms对应角度0°-180°这里有个容易混淆的概念占空比和脉宽。虽然PWM常用占空比描述但舵机实际响应的是高电平持续时间。比如0.5ms脉宽 → 0°1.5ms脉宽 → 90°2.5ms脉宽 → 180°2. STM32硬件配置与CubeMX设置我用的是STM32F103C8T6蓝板性价比高且资源丰富。在CubeMX中配置时这几个关键点需要注意2.1 定时器选择TIM4的CH3通道对应PB8引脚正好适合驱动舵机。配置步骤在CubeMX中启用TIM4选择Channel3为PWM Generation CH3设置Prescaler和Counter Period具体参数计算 假设系统时钟72MHz要实现50Hz PWMPrescaler 7172MHz/(711)1MHzCounter Period 199991MHz/2000050Hz注意极性要设为High否则舵机会反向运动2.2 引脚复用配置PB8需要配置为复用推挽输出模式。我遇到过因为忘记配置GPIO模式导致信号输出异常的情况建议检查GPIO mode: Alternate Function Push-PullPull-up/Pull-down: No pullMaximum output speed: High3. PWM与角度映射的数学关系舵机角度控制的核心是建立CCR寄存器值与实际角度的映射关系。经过多次实测我总结出这个公式CCR_Value (Angle / 180) * (MAX_CCR - MIN_CCR) MIN_CCR对于SG90MIN_CCR 500 对应0.5msMAX_CCR 2500 对应2.5ms例如要转动到90°CCR (90/180)*2000 500 1500在代码中可以这样实现uint16_t AngleToCCR(uint8_t angle) { return (uint16_t)(angle / 180.0 * 2000 500); }4. 完整工程实现与调试技巧4.1 工程结构建议采用模块化编程main.c主循环和初始化sg90.c/h舵机驱动封装tim.cPWM配置4.2 关键代码实现在main.c中添加HAL_TIM_PWM_Start(htim4, TIM_CHANNEL_3); while(1) { for(int angle0; angle180; angle45) { __HAL_TIM_SET_COMPARE(htim4, TIM_CHANNEL_3, AngleToCCR(angle)); HAL_Delay(1000); } }4.3 常见问题排查舵机不转动检查电源是否足够建议单独5V供电用示波器测量PWM信号波形确认TIM4_CH3输出使能角度不准确校准0°和180°的CCR值检查机械结构是否卡顿抖动问题增加电源滤波电容确保PWM频率稳定在50Hz5. 进阶应用与性能优化5.1 多舵机控制通过一个定时器可以控制多个舵机使用TIM4的多个通道CH1-CH4配置不同GPIO为复用功能分别设置各自的CCR值5.2 平滑运动控制直接跳变角度会导致舵机抖动可以添加缓动函数void SmoothMove(uint8_t target_angle, uint8_t speed) { uint8_t current GetCurrentAngle(); while(current ! target_angle) { current (current target_angle) ? 1 : -1; __HAL_TIM_SET_COMPARE(htim4, TIM_CHANNEL_3, AngleToCCR(current)); HAL_Delay(speed); } }5.3 低功耗优化在电池供电场景下使用PWM休眠模式动态调整PWM频率在不运动时切断舵机电源6. 实际项目经验分享在机械臂项目中我发现SG90的扭矩不足问题很明显。解决方案选择金属齿轮版本的MG90S采用双舵机并联驱动增加减速机构另一个坑是电源干扰。当多个舵机同时运动时电压跌落会导致MCU复位。我的应对方案使用4700μF电容稳压采用独立电源供电添加TVS二极管保护调试时建议先用LED观察PWM输出再用逻辑分析仪验证波形。记住一点舵机的运动滞后约100-200ms编程时要留出足够的稳定时间。