舵机SG90详解
舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。其中,SG90 舵机以其高效、稳定的性能特点,成为了许多工程师和爱好者的首选,无论是航模、云台、机器人、智能小车中都有它的身影。
本文将深入探讨SG90舵机的技术规格、工作原理和使用方法,为您展现 SG90 舵机的功能和无限可能。
1. 源码下载及前置阅读
本文首发良许嵌入式网:https://www.lxlinux.net/e/ ,欢迎关注!
本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):
https://www.lxlinux.net/e/stm32/sg90-tutorial.html
如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。
- 了解不同的下载程序方法,为你的嵌入式开发提供更多选择:STM32下载程序的五种方法
- 手把手让你掌握MDK的使用方式和技巧,助你更高效地进行开发:一文教你使用MDK开发工具
- 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)
往期精彩教程,有兴趣的小伙伴可以看看。
- 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)
- 深入浅出,帮助您理解和应用MQTT协议:万字猛文:MQTT原理及案例
- 通俗易懂的 GPIO 介绍与实践:如何快速成为点灯大师?
| 作者简介 |
|---|
| 大家好,我是良许,博客里所有的文章皆为我的原创。 下面是我的一些个人介绍,欢迎交个朋友: · 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°
引脚接线参考如下:
| SG90 | STM32 |
|---|---|
| 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.5ms | 0° | 2.5% |
| 1.0ms | 45° | 5.0% |
| 1.5ms | 90° | 7.5% |
| 2.0ms | 135° | 10.0% |
| 2.5ms | 180° | 12.5% |
4. 编程实战
现在我们就动手,让 SG90 每秒转动一下,0° -> 20° -> 40° -> 100° -> 180° 如此循环。
4.1 硬件接线
本教程使用的硬件如下:
- 单片机:STM32F103C8T6
- 舵机:SG90
- 烧录器:ST-LINK V2
接线如下:
| SG90 | STM32 |
|---|---|
| PWM 信号线(橙色线) | A0 |
| VCC(红线) | 3.3/5V |
| GND(棕色线) | GND |
烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。
| ST-Link V2 | STM32 |
|---|---|
| SWCLK | SWCLK |
| SWDIO | SWDIO |
| GND | GND |
| 3.3V | 3V3 |
接好如下图:
我用的是我自己打的板子,上官二号。大家可以用自己的板子,是 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_CH1TIM_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 随你挑!
有收获?希望老铁们来个三连击,给更多的人看到这篇文章
推荐阅读:
- 程序员必备编程资料大全
- 程序员必备软件资源
欢迎关注我的博客:良许嵌入式教程网,满满都是干货!
相关文章:
舵机SG90详解
舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。其中,SG90 舵机以其高效、稳定的性能特点,成为了许多工程师和爱好者的首选,无论是航模、云台、机器人、智能…...
程序设计考题汇总(四:SQL练习)
文章目录 查询结果限制返回行数 查询结果限制返回行数 select device_id from user_profile LIMIT 2;...
明达IOT平台助力工业废水运维智能化
背景简介 相较于生活污水,工业废水的处理挑战性更高,原因在于其源于多样化的工业生产流程,成分复杂且多变,可能包含重金属、有毒化学…...
深入理解 Ansible Playbook:组件与实战
目录 1 playbook介绍 2 YAML语言 2.1语法简介 2.2数据类型 3 Playbook核心组件 3.1 hosts组件 3.2 remote_user组件 3.3 task列表和action组件 3.4 handlers 3.5 tags组件 3.6 其他组件说明 1 playbook介绍 playbook 剧本是由一个或多个"play"组成的列表。…...
JavaEE初阶——多线程(线程安全-锁)
复习上节内容(部分-掌握程度不够的) 加锁,解决线程安全问题。 synchronized关键字,对锁对象进行加锁。 锁对象,可以是随便一个Object对象(或者其子类的对象),需要关注的是ÿ…...
Stable Diffusion 提示词语法
1.提示词基础 1.提示词之间用英文逗号,分隔 2.提示词之间是可以换行的 3.权重默认为1,越靠前权重越高 4.数量控制在75个单位以内 2.提示词各种符号的意义 2.1 ()、[]、{}符号 权重值()小括号[]中括号{}大括号默认1111层()1.1[]0.9{}1.052层(()) 1.121.21[[]]0.920.81{{}}1.…...
【功能安全】安全确认
目录 01 功能安全确认介绍 02 安全确认用例 03 安全确认模板 01 功能安全确认介绍 定义: 来源...
在pycharm2024.3.1中配置anaconda3-2024-06环境
version: anaconda3-2024.06-1 pycharm-community-2024.3.1 1、安装anaconda和pycharm 最新版最详细Anaconda新手安装配置环境创建教程_anaconda配置-CSDN博客 【2024最新版】超详细Pycharm安装保姆级教程,Pycharm环境配置和使用指南,看完这一篇就够了…...
linux不同发行版中的主要差异
一、初始化系统 Linux不同发行版中的系统初始化系统(如 System V init、Upstart 或 systemd) System V init: 历史:System V init 是最传统的 Linux 系统初始化系统,起源于 Unix System V 操作系统。运行级别ÿ…...
概率论得学习和整理29: 用EXCEL 描述二项分布
目录 1 关于二项分布的基本内容 2 二项分布的概率 2.1 核心要素 2.2 成功K次的概率,二项分布公式 2.3 期望和方差 2.4 具体试验 2.5 概率质量函数pmf 和cdf 3 二项分布的pmf图的改进 3.1 改进折线图 3.2 如何生成这种竖线图呢 4 不同的二项分布 4.1 p0.…...
C++打造局域网聊天室第九课: 客户端队列及其处理线程
文章目录 前言一、添加客户端队列的参数初始化二、相关函数总结 前言 C打造局域网聊天室第九课: 客户端队列及其处理线程 一、添加客户端队列的参数初始化 在Server.cpp的 ListenThreadFunc()函数内的其他操作处实现客户端队列的添加。 首先进行部分参数的初始化…...
请求go web后端接口 java安卓端播放视频
前端代码 添加gradle依赖 implementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0 添加访问网络权限 <uses-permission android:name"android.permission.INTERNET" />允许http 请求请求 andro…...
XML Schema 复合类型 - 混合内容
XML Schema 复合类型 - 混合内容 XML Schema 是一种用于定义 XML 文档结构和内容的语言。在 XML Schema 中,复合类型是一种包含其他元素和/或属性的复杂类型。混合内容(Mixed Content)是复合类型的一种特殊形式,它允许元素包含其…...
第8章 搬移特性
8.1 搬移函数 模块化是优秀软件设计的核心所在,好的模块化能够让我在修改程序时只需理解程序的一小部分。为了设计出高度模块化的程序,我得保证互相关联的软件要素都能集中到一块,并确保块与块之间的联系易于查找、直观易懂。同时,…...
ARM/Linux嵌入式面经(五九):海尔
1.以后打算在哪里工作 问题回答: 1. 以后打算在哪里工作? 回答这个问题时,我首先会考虑我的个人目标、职业规划以及家庭和生活因素。从职业发展的角度来看,我希望能够在技术氛围浓厚、创新能力强、且能提供良好职业成长机会的地方工作。具体来说,我对以下几个方向特别感…...
java中的List、数组和set
在Java中,List、数组(Array)和Set 是三种常用的数据结构,它们各自有不同的特性、用途和实现方式。下面我们将深入探讨这三者的特点、区别以及它们在 Java 中的常见使用场景。 1. 数组(Array) 特性&#x…...
freeswitch(配置文件结构)
vars.xml<X-PRE-PROCESS cmd="set" data="default_password=1234"/>default_password:设置默认密码,为安全起见,建议在部署后立即更改此密码,以防止盗用。<X-PRE-PROCESS cmd=<...
ARMS 用户体验监控正式发布原生鸿蒙应用 SDK
作者:羿莉 背景 对企业数据进行敏感数据扫描和保护可以提升企业或组织的数据安全。一方面敏感数据可能包括个人身份信息、财务记录、医疗记录等,定期扫描这些数据可以防止未经授权的访问和泄露。 另一方面,许多国家和地区都有关于数据保护的…...
使用 esrally race 测试 Elasticsearch 性能:实践指南
在 Elasticsearch 性能优化和容量规划中,使用 esrally 进行基准测试是官方推荐的方式。通过 esrally race 命令,您可以针对不同的数据集与挑战类型,对 Elasticsearch 集群进行精确的性能评估。本文将简要介绍常用的数据集与挑战类型ÿ…...
OkHttp源码分析:分发器任务调配,拦截器责任链设计,连接池socket复用
目录 一,分发器和拦截器 二,分发器处理异步请求 1.分发器处理入口 2.分发器工作流程 3.分发器中的线程池设计 三,分发器处理同步请求 四,拦截器处理请求 1.责任链设计模式 2.拦截器工作原理 3.OkHttp五大拦截器 一&#…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...
