STM32控制舵机完全指南:从原理到实战(适合小白入门)

STM32控制舵机完全指南:从原理到实战

一、舵机基础原理

1.1 舵机是什么?

舵机(Servo Motor)是一种位置伺服驱动器,它可以根据控制信号精确地旋转到特定角度并保持在该位置。舵机内部包含直流电机、减速齿轮组、控制电路和电位器(用于检测当前角度)。

1.2 舵机如何工作?

舵机通过接收PWM(脉冲宽度调制)信号来控制角度。这个信号有三个关键特征:

  • 频率固定:通常为50Hz(周期20ms)
  • 脉宽可变:高电平持续时间在0.5ms-2.5ms之间变化
  • 脉宽与角度对应
    • 0.5ms → 0度
    • 1.5ms → 90度
    • 2.5ms → 180度

二、硬件准备与连接

2.1 所需材料

  • STM32开发板(如STM32F103C8T6)
  • 舵机(常见SG90)
  • 杜邦线若干
  • 5V电源(注意:STM32的3.3V可能无法驱动舵机)

2.2 接线方式

舵机线缆颜色STM32连接点
红色电源+5V电源
棕色地线GND
黄色信号线PWM输出引脚(如PA6)

重要提示

  • 当驱动多个舵机时,建议使用外部电源供电
  • 确保共地(STM32与舵机电源地连接在一起)

三、STM32 PWM配置

3.1 PWM基础概念

PWM(脉冲宽度调制)是控制舵机的核心技术。STM32的定时器可以生成精确的PWM信号:

  • ARR(自动重装载值):决定PWM周期
  • CCR(捕获/比较值):决定脉冲宽度(占空比)

3.2 CubeMX配置步骤

  1. 打开STM32CubeMX,选择对应芯片
  2. 配置时钟树,确保定时器时钟正确(如72MHz)
  3. 选择定时器(如TIM3)和通道(如CH1)
  4. 设置模式为"PWM Generation CH1"
  5. 参数设置:
    • Prescaler(分频系数):71
    • Counter Period(ARR):1999
    • Pulse(初始CCR):150(对应1.5ms)

3.3 关键代码解析

PWM初始化代码(以TIM3通道1为例):

// PWM初始化函数
void PWM_Init(void) {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct;
    
    // 1. 使能时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 2. GPIO配置
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // 3. 定时器基础配置
    TIM_TimeBaseStruct.TIM_Prescaler = 72 - 1;  // 72MHz/72 = 1MHz
    TIM_TimeBaseStruct.TIM_Period = 20000 - 1; // 20ms周期
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
    
    // 4. PWM通道配置
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStruct);
    
    // 5. 启动定时器
    TIM_Cmd(TIM3, ENABLE);
}

四、舵机控制实战

4.1 角度控制函数

将PWM脉宽转换为角度控制:

// 设置舵机角度(0-180度)
void Servo_SetAngle(float angle) {
    // 角度转换为CCR值:500(0°) ~ 2500(180°)
    uint16_t pulse = (angle / 180) * 2000 + 500;
    TIM_SetCompare1(TIM3, pulse);  // 更新CCR值
}

4.2 主程序示例

#include "stm32f10x.h"
#include "pwm.h"
#include "delay.h"

int main(void) {
    Delay_Init();
    PWM_Init();
    
    while(1) {
        // 0° → 90° → 180°循环
        Servo_SetAngle(0);
        Delay_ms(1000);
        
        Servo_SetAngle(90);
        Delay_ms(1000);
        
        Servo_SetAngle(180);
        Delay_ms(1000);
    }
}

4.3 按键控制进阶版

通过按键控制角度增减:

uint8_t key = KEY_GetNum();
if(key == 1) {  // KEY1按下
    angle += 30;
    if(angle > 180) angle = 0;
    Servo_SetAngle(angle);
    OLED_ShowNum(1, 7, angle, 3);  // 显示当前角度
}

五、常见问题与调试技巧

5.1 舵机不转动

检查步骤

  1. 确认电源电压≥4.8V
  2. 检查信号线连接是否正确
  3. 用示波器测量PWM波形
  4. 检查代码中定时器和GPIO配置

5.2 舵机抖动或不稳定

解决方案

  1. 增加电源滤波电容(如100μF)
  2. 确保电源电流足够(单个舵机约需300mA)
  3. 检查PWM信号是否稳定

5.3 角度不准确

校准方法

// 实际测试后调整公式
void Servo_Calibrate(float angle) {
    // 自定义校准参数
    uint16_t pulse = (angle / 180) * 1800 + 600;  // 根据实测调整
    TIM_SetCompare1(TIM3, pulse);
}

六、项目扩展

6.1 多舵机控制

STM32的单个定时器可以同时控制4路舵机(通用定时器):

// 初始化TIM3的4个通道
TIM_OC1Init(TIM3, &TIM_OCInitStruct);  // CH1
TIM_OC2Init(TIM3, &TIM_OCInitStruct);  // CH2
// ...其他通道类似

6.2 机械臂控制实例

6自由度机械臂控制

void RoboticArm_Control(float angles[6]) {
    Servo_SetAngle(0, angles[0]);  // 底座
    Servo_SetAngle(1, angles[1]);  // 肩部
    Servo_SetAngle(2, angles[2]);  // 肘部
    // ...其他关节
}

6.3 使用中断优化

通过定时器中断实现平滑运动:

void TIM3_IRQHandler(void) {
    if(TIM_GetITStatus(TIM3, TIM_IT_Update)) {
        static uint8_t step = 0;
        float target_angle = 90 + 30 * sin(step++ * 0.1);
        Servo_SetAngle(target_angle);
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }
}

七、学习资源推荐

  1. 官方文档

    • 《STM32参考手册》定时器章节
    • STM32CubeMX用户手册
  2. 开发工具

    • 逻辑分析仪(观察PWM波形)
    • STM32CubeMonitor(实时调试)
  3. 进阶项目

    • 双足机器人平衡控制
    • 云台跟踪系统
    • 自动窗帘控制器

完整工程下载
STM32舵机控制示例代码

通过本指南,您已经掌握了从基础原理到实际应用的STM32舵机控制技术。建议按照以下步骤实践:

  1. 从单个舵机控制开始
  2. 尝试按键交互控制
  3. 实现多舵机协同
  4. 最后开发完整项目(如机械臂)

遇到问题时,记住检查电源、信号和代码配置这三个关键环节。祝您在嵌入式开发之路上越走越远!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值