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为例):

c 复制代码
// 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脉宽转换为角度控制:

c 复制代码
// 设置舵机角度(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 主程序示例

c 复制代码
#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 按键控制进阶版

通过按键控制角度增减:

c 复制代码
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 角度不准确

校准方法

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

六、项目扩展

6.1 多舵机控制

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

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

6.2 机械臂控制实例

6自由度机械臂控制

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

6.3 使用中断优化

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

c 复制代码
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. 最后开发完整项目(如机械臂)

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

相关推荐
polarislove02149 小时前
10.1 [ADC] 逐次逼近型ADC-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
qq_672592759 小时前
STM32超声测距离的测量精度评估
stm32·硬件架构·硬件工程
谈思汽车9 小时前
TEE or HSM/SE?车载安全技术选型指南
嵌入式硬件·安全·智能汽车·可信执行环境·汽车信息安全
单片机系统设计9 小时前
基于STM32的智能垃圾桶/语音分类/自动开盖/矩阵按键
stm32·矩阵·毕业设计·语音识别·智能垃圾桶
-曾牛10 小时前
【汇编语言入门】从第一个加法程序吃透汇编核心基础
汇编·单片机·嵌入式硬件·汇编语言·病毒分析·lcx·逆向开发
IT方大同10 小时前
ADC&DAC概述
嵌入式硬件
三品吉他手会点灯11 小时前
STM32F103 学习笔记-21-串口通信(第3节)-STM32串口初始化结构体和固件库讲解
笔记·stm32·单片机·嵌入式硬件·学习
Lester_110111 小时前
单片机EEPROM写入数据之前为什么要先擦除?
单片机·嵌入式软件
点灯小铭11 小时前
基于单片机的多功能LCD万年历时钟设计与温度显示系统
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
点灯小铭11 小时前
基于单片机的玉米播种机漏播检测装置设计与实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业