舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。其中,SG90 舵机以其高效、稳定的性能特点,成为了许多工程师和爱好者的首选,无论是航模、云台、机器人、智能小车中都有它的身影。

本文将深入探讨SG90舵机的技术规格、工作原理和使用方法,为您展现 SG90 舵机的功能和无限可能。

1. 源码下载及前置阅读

本文首发良许嵌入式网:https://www.lxlinux.net/e/ ,欢迎关注!

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/sg90-tutorial.html

如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。

往期精彩教程,有兴趣的小伙伴可以看看。

作者简介
大家好,我是良许,博客里所有的文章皆为我的原创。
下面是我的一些个人介绍,欢迎交个朋友:
· 211工科硕士,国家奖学金获得者;
· 深耕嵌入式11年,前世界500强外企高级嵌入式工程师;
· 书籍《速学Linux作者》,机械工业出版社专家委员会成员;
· 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万;
· 靠自媒体连续年入百万,靠自己买房买车。

我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:

电子书链接:https://www.lxlinux.net/1024.html

2. SG90介绍

2.1 型号介绍

市面上常见的舵机型号有 SG90、MG90S、MG995、MG996R 等等,主要是扭矩大小、工作电压大小、齿轮材质塑料或金属的不同。

一般分为180度和360度:

  • 180度:可以控制旋转角度、有角度定位。上电后舵机自动复位到0度,通过一定参数的脉冲信号控制它的角度。
  • 360°舵机版本不可控制角度,只能控制顺时针旋转、逆时针旋转、停止和调节转速。

我们今天的主角是 SG90,180度版。

2.2 工作参数及引脚介绍

工作参数如下:

  • 工作扭矩:1.6kg/cm
  • 反应速度:0.12 - 0.13秒/60°
  • 死区设定:5us
  • 转动角度:常见0°、90°、180°、360°
  • 齿轮材质:尼龙塑料齿
  • 工作电压:3V - 6V
  • 温度范围:-30° ~ +60°

引脚接线参考如下:

SG90STM32
PWM 信号线(橙色线)任意GPIO
VCC(红线)3.3/5V
GND(棕色线)GND

3. SG90原理

舵机的控制信号是通过脉冲宽度调制(PWM)来实现的。PWM 信号的周期通常为20ms,而脉冲宽度则在 0.5ms 至 2.5ms 之间变化。这个脉冲宽度与舵盘的位置呈线性关系,范围从0度到180度。

当给舵机提供特定宽度的脉冲信号时,输出轴会保持在相应的角度上,不受外界转矩的影响,直到接收到不同宽度的脉冲信号才会改变输出角度,使舵盘移动到新的位置。舵机内部有一个基准电路,产生周期为 20ms、宽度为 1.5ms 的基准信号。同时,还有一个比较器,用于将外部输入信号与基准信号进行比较,以确定转动方向和幅度,并生成驱动电机转动的信号。

控制电路板接收来自信号线的 PWM 控制信号,然后控制电机的转动。电机带动一系列齿轮组,在经过减速传动后,将力量传递到输出舵盘上。舵机的输出轴与位置反馈电位计相连,当舵盘旋转时,位置反馈电位计也会随之变化,向控制电路板输出电压信号进行反馈。控制电路板根据位置反馈信号判断当前位置,并决定电机的转动方向和速度,以实现目标停止。

为了控制舵机,需要使用单片机来生成周期为 20ms 的脉冲信号,并通过控制脉冲的高电平时间在 0.5ms 至 2.5ms 之间来控制舵机的角度。这样,我们可以通过调整 PWM 信号的脉冲宽度来精确控制舵机的位置和运动。

以 SG90,180度版为例,那么对应的控制关系是这样的:

脉冲高电平角度占空比
0.5ms2.5%
1.0ms45°5.0%
1.5ms90°7.5%
2.0ms135°10.0%
2.5ms180°12.5%

4. 编程实战

现在我们就动手,让 SG90 每秒转动一下,0° -> 20° -> 40° -> 100° -> 180° 如此循环。

4.1 硬件接线

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6
  • 舵机:SG90
  • 烧录器:ST-LINK V2

接线如下:

SG90STM32
PWM 信号线(橙色线)A0
VCC(红线)3.3/5V
GND(棕色线)GND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

我用的是我自己打的板子,上官二号。大家可以用自己的板子,是 STM32F103C8T6 就行。

4.2 舵机初始化

将舵机 PWM 引脚进行一个初始化。

void SG_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_0;                           /* PWM引脚 */
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;                     /* 复用推挽 */
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;                /* 低速 */
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);                     /* 初始化PWM引脚 */
}

4.3 定时器初始化

我们 PWM 引脚接 A0,对应的是定时器2和通道1,以下是初始化代码。

void TIM2_Init(void)
{
    //PA0     ------> TIM2_CH1
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};            /* 定时器设置结构体 */
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};

    htim2.Instance = TIM2;                                      /* 通用定时器2 */
    htim2.Init.Prescaler = 7199;                                /* 预分频系数 */
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;                /* 递增计数模式 */
    htim2.Init.Period = 199;                                    /* 自动装载值 */
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;          /* 时钟分频因子 */
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_Base_Init(&htim2);
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
    HAL_TIM_PWM_Init(&htim2);
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
    if(tim_baseHandle->Instance==TIM2)
    {
        /* 定时器2时钟使能 */
        __HAL_RCC_TIM2_CLK_ENABLE();
    }
}

4.4 舵机控制

已知 PWM 信号的周期为20ms;高电平 0.5ms 指向 0° 位置,2.5ms 指向 180° 位置。如果我们要指向 angle°:

2.5-0.5=2ms,对应于180°

CCRx / (199 + 1) * 20 = 0.5 +(angle / 180)× 2

于是 CCRx =(1.0 / 9.0) * angle + 5.0

void SG_Control(uint16_t angle)
{
   float CCRx;
   CCRx =(1.0 / 9.0) * angle + 5.0;                             //占空比值 = 1/9 * 角度 + 5
   __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (uint16_t )CCRx);
}

4.5 主函数

主函数如下:

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    TIM2_Init();                        /* 定时器4初始化 */
    SG_Init();                          /* 舵机初始化 */
    HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);

    while(1)
    {
        SG_Control(0);                  //舵机旋转到0度
        HAL_Delay(1000);
        SG_Control(20);                 //舵机旋转到20度
        HAL_Delay(1000);
        SG_Control(40);                 //舵机旋转到40度
        HAL_Delay(1000);
        SG_Control(100);                //舵机旋转到100度
        HAL_Delay(1000);
        SG_Control(180);                //舵机旋转到180度
        HAL_Delay(1000);
    }
}

4.6 运行效果

SG90 每秒转动一下,0° -> 20° -> 40° -> 100° -> 180° 如此循环。

5. 总结

通过了解 SG90 舵机的工作原理和特点,我们可以更好地利用它的潜力,为我们的项目带来更多可能性和创新。无论是初学者还是专业工程师,SG90 舵机都是一个很不错的模块,它可以帮助我们实现精确的位置控制和稳定的运动性能。

希望本文能够让你对 SG90 舵机有更深入的了解,并且能够在你的项目中发挥出它的优势。感谢各位看官,peace and love!

另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。

刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

欢迎关注我的博客:良许嵌入式教程网,满满都是干货!


良许
1k 声望1.8k 粉丝