1.MG996R舵机的性能参数

参数数值
产品型号MG995/MG996R
产品重量55 g
工作扭矩13 kg·cm
反应速度53-62 R/M
使用温度-30°C ~ +55°C
死区设置4 微秒
插头类型JR、FUTABA 通用
转动角度180°(左90°,右90°)
舵机类型数码舵机
使用电压3.0 - 7.2 V
工作电流100 mA
结构材质部分铜齿、空心杯电机
线长≈ 25 cm
适用范围双足机器人、机械手、遥控船、适合 50-90 级甲醇固定翼飞机、26-50 CC 汽油固定翼飞机等模型

2.MG996R 接线方式

2.1实物图

2.2接线方式

  • 橙色线——信号线

  • 黑色线——GND

  • 红色线——VCC(一般接5V)

3. 单片机驱动 MG996R 舵机原理

MG996R 舵机是一种常见的 数字舵机,它的转动角度是通过 PWM(脉宽调制信号) 来控制的。单片机(比如 STM32)只要能输出符合要求的 PWM 信号,就可以精确控制舵机转动到指定角度。

3.1 什么是 PWM 信号?

  • PWM 全称 Pulse Width Modulation(脉宽调制)。

  • 简单理解:就是输出一个“高低电平交替”的方波信号。

  • 控制舵机的关键点在于:脉宽的长短决定舵机转的角度

3.2 舵机对 PWM 的基本要求

MG996R 使用 标准 PWM 控制,主要参数如下:

  • 周期(Period):20 ms(也就是 50 Hz 的频率)。 👉 每隔 20 ms,舵机会“读一次”信号,更新自己要到的角度。

  • 占空比(Duty Cycle):在 20 ms 的周期里,高电平的持续时间不同,舵机角度也不同。

脉宽 (高电平持续时间)对应角度
0.5 ms
1.0 ms45°
1.5 ms90°
2.0 ms135°
2.5 ms180°

也就是说:

  • 当 PWM 高电平只有 0.5ms,舵机会转到最左边(0°);

  • 当 PWM 高电平是 1.5ms,舵机会正中间(90°);

  • 当 PWM 高电平到 2.5ms,舵机会转到最右边(180°)。

3.3 STM32 控制舵机的原理

STM32 单片机内部的 定时器(Timer) 可以产生 PWM 信号。使用 HAL 库配置时,关键步骤是:

  1. 设置定时器时钟 确保能产生精确的 20 ms 周期。

  2. 配置 PWM 模式 把定时器的某个通道设为 PWM 输出,并把引脚映射到外部(比如 PA5、PB0 等)。

  3. 改变占空比 通过修改定时器的比较寄存器(CCR 值),就能调整 PWM 脉宽,从而控制舵机角度。

举个例子:

  • CCR = 500 → 脉宽约 0.5 ms → 舵机转到 0°

  • CCR = 1500 → 脉宽约 1.5 ms → 舵机转到 90°

  • CCR = 2500 → 脉宽约 2.5 ms → 舵机转到 180°

4.STM32 HAL库驱动MG996R舵机

4.1STM32CUBEMX初始化

HAL 库下 PWM 初始化步骤

①确定定时器时基

假设使用 84 MHz 主频,希望得到 20 ms 周期(50 Hz):

// 84 MHz / (Prescaler+1) / (Period+1) = 50 Hz
Prescaler = 84-1;   // 72 MHz / (71+1) = 1 MHz
Period    = 20000-1; // 1 MHz / (19999+1) = 50 Hz

注:这里我用到的是 STM32F407VET6 的 TIM12、TIM13 和 TIM14。它们都挂在 APB1 总线上。在主频 168 MHz 的情况下,APB1 时钟是 84 MHz,所以定时器相关的计算就以 84 MHz 为基准。

②CubeMX 初始化定时器 打开 CubeMX → Pinout & Configuration → Timers → 选择一个支持 PWM 的定时器。

Clock Source配置为Intenal Clock
​
设定:
  • Prescaler = 84-1

  • Counter Period = 20000-1

  • Channel 模式设为 PWM Generation CHx

  • 把对应引脚设置为 PWM 输出。

4.2核心代码

1.servo_app.c代码

#include "servo_app.h"
​
// ================== 舵机参数 ==================
// MG996R 是常用的舵机,它通过 PWM 脉宽来控制角度。
// 一般来说:
//   0.5ms 脉宽 = 0°
//   1.5ms 脉宽 = 90°
//   2.5ms 脉宽 = 180°
// 所以我们先定义最小/最大脉宽值,后续角度计算会用到。
#define SERVO_DEFAULT_MIN_PULSE 500   // 对应 0° 时的脉宽 (单位: us,对应0.5ms)
#define SERVO_DEFAULT_MAX_PULSE 2500  // 对应 180° 时的脉宽 (单位: us,对应2.5ms)
​
// 定义四个舵机对象(左右两边各两个)
Servo_MG996R_t MG996R_LEFT1;
Servo_MG996R_t MG996R_LEFT2;
Servo_MG996R_t MG996R_RIGHT1;
Servo_MG996R_t MG996R_RIGHT2;
​
​
// ================== 舵机初始化 ==================
void Servo_Init(Servo_MG996R_t* servo, TIM_HandleTypeDef* htim, uint32_t channel)
{// 保存定时器和通道信息servo->htim = htim;servo->channel = channel;servo->min_pulse = SERVO_DEFAULT_MIN_PULSE;servo->max_pulse = SERVO_DEFAULT_MAX_PULSE;// 启动对应定时器通道的 PWM 输出HAL_TIM_PWM_Start(servo->htim, servo->channel);
}
​
​
// ================== 设置舵机角度 ==================
void Servo_SetAngle(Servo_MG996R_t* servo, float angle)
{// 1. 限制角度范围在 [0°, 180°] 之间if (angle < 0) angle = 0;if (angle > 180) angle = 180;// 2. 根据角度 -> 换算为脉宽//   角度 0° = min_pulse//   角度 180° = max_pulseuint16_t pulse = servo->min_pulse + (uint16_t)((servo->max_pulse - servo->min_pulse) * angle / 180.0f);// 3. 把换算出来的脉宽值,交给 PWM 输出Servo_SetPulse(servo, pulse);
}
​
​
// ================== 设置舵机 PWM 脉宽 ==================
void Servo_SetPulse(Servo_MG996R_t* servo, uint16_t pulse)
{// 1. 限制脉宽在 [min_pulse, max_pulse] 范围if (pulse < servo->min_pulse) pulse = servo->min_pulse;if (pulse > servo->max_pulse) pulse = servo->max_pulse;// 2. 直接写入定时器的比较寄存器 (CCR)//    这会改变 PWM 占空比,从而改变舵机角度__HAL_TIM_SET_COMPARE(servo->htim, servo->channel, pulse);
}
​
​
// ================== 校准舵机脉宽范围 ==================
void Servo_Calibrate(Servo_MG996R_t* servo, uint16_t min_pulse, uint16_t max_pulse)
{// 用户可以根据自己舵机的实际情况调整servo->min_pulse = min_pulse;servo->max_pulse = max_pulse;
}
​
​
// ================== 初始化所有舵机 ==================
void Servo_Init_All(void)
{// 左边两个舵机挂在 TIM12 (CH1, CH2)Servo_Init(&MG996R_LEFT1, &htim12, TIM_CHANNEL_1);Servo_Init(&MG996R_LEFT2, &htim12, TIM_CHANNEL_2);// 右边两个舵机挂在 TIM13 (CH1) 和 TIM14 (CH1)Servo_Init(&MG996R_RIGHT1, &htim13, TIM_CHANNEL_1);Servo_Init(&MG996R_RIGHT2, &htim14, TIM_CHANNEL_1);
}
​
​
// ================== 演示任务:让舵机转到不同角度 ==================
void Servo_Task(void)
{// 左1 = 0°Servo_SetAngle(&MG996R_LEFT1, 0);// 左2 = 45°Servo_SetAngle(&MG996R_LEFT2, 45);// 右1 = 90°Servo_SetAngle(&MG996R_RIGHT1, 90);// 右2 = 135°Servo_SetAngle(&MG996R_RIGHT2, 135);
}
​

2.servo_app.h代码

#ifndef __SERVO_APP_H__
#define __SERVO_APP_H__
​
#include "MyDefine.h"
typedef struct {TIM_HandleTypeDef* htim;  // 定时器句柄uint32_t channel;         // 定时器通道uint16_t min_pulse;       // 最小脉宽(0度位置)uint16_t max_pulse;       // 最大脉宽(180度位置)
} Servo_MG996R_t;
​
// 初始化舵机
void Servo_Init(Servo_MG996R_t* servo, TIM_HandleTypeDef* htim, uint32_t channel);
​
// 设置舵机角度 (0-180度)
void Servo_SetAngle(Servo_MG996R_t* servo, float angle);
​
// 设置舵机原始脉宽值
void Servo_SetPulse(Servo_MG996R_t* servo, uint16_t pulse);
​
// 校准舵机最小和最大脉宽
void Servo_Calibrate(Servo_MG996R_t* servo, uint16_t min_pulse, uint16_t max_pulse);
​
void Servo_Init_All(void);
void Servo_Task(void);
​
​
#endif
​

3.main.c 示例代码

/* USER CODE BEGIN Includes */
#include "servo_app.h"   // 引入你写的舵机驱动头文件
/* USER CODE END Includes */
​
int main(void)
{/* MCU Configuration--------------------------------------------------------*/
​/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();
​/* Configure the system clock */SystemClock_Config();
​/* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM12_Init();   // 配置 TIM12MX_TIM13_Init();   // 配置 TIM13MX_TIM14_Init();   // 配置 TIM14
​/* USER CODE BEGIN 2 */// === 初始化所有舵机 ===Servo_Init_All();/* USER CODE END 2 */
​/* Infinite loop *//* USER CODE BEGIN WHILE */while (1){// === 演示舵机动作 ===Servo_Task();   // 设置 0°、45°、90°、135°HAL_Delay(2000); // 停 2 秒,方便观察动作// 也可以手动设置某个舵机的角度,例如:Servo_SetAngle(&MG996R_LEFT1, 180);  // 左1转到 180°HAL_Delay(1000);
​Servo_SetAngle(&MG996R_LEFT1, 90);   // 左1转回 90°HAL_Delay(1000);}/* USER CODE END WHILE */
}
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96829.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96829.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96829.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[frontend]mermaid code2image

hello everyone, welcome to my bolg, here i will introduce something interesting, and if you are interested it, please just let me know. follow me and send me a message are both avaiable. what is mermaid? Mermaid 是一个工具&#xff0c;它能让你用简单的文字代…

Jakarta EE 在 IntelliJ IDEA 中开发简单留言板应用的实验指导(附完整代码)

Jakarta EE 在 IntelliJ IDEA 中开发简单留言板应用的实验指导(附完整代码) 摘要:实验基于Jakarta EE 9+(兼容Tomcat 10+)、Maven作为构建工具,并在IntelliJ IDEA 2023.2(Community版免费)中进行。项目使用Maven Archetype WebApp模板生成基础结构,然后升级到J…

JavaScript经典面试题一(JavaScript基础)

目录 一、JavaScript中的变量提升 1. 机制 2. 示例 3. 注意事项 4. 总结 二、var、let和const的区别。 1. 作用域&#xff08;Scope&#xff09; 2. 变量提升&#xff08;Hoisting&#xff09; 3. 重新赋值和重新声明 4. 示例 示例1&#xff1a;作用域和块级行为 示…

数据库造神计划第七天---增删改查(CRUD)(3)

&#x1f525;个人主页&#xff1a;寻星探路 &#x1f3ac;作者简介&#xff1a;Java研发方向学习者 &#x1f4d6;个人专栏&#xff1a;《从青铜到王者&#xff0c;就差这讲数据结构&#xff01;&#xff01;&#xff01;》、 《JAVA&#xff08;SE&#xff09;----如此简单&a…

AWS SQS 可观测性最佳实践

AWS SQS AWS SQS&#xff08;Amazon Simple Queue Service&#xff09;是一种完全托管的消息队列服务&#xff0c;用于在分布式系统中解耦和缓冲消息。它支持高可用性、可扩展性和安全性&#xff0c;能够处理大量消息&#xff0c;确保消息的可靠传输和顺序性。开发者可以轻松集…

AI推理范式:从CoT到ReAct再到ToT的进化之路

在人工智能领域&#xff0c;如何让模型像人类一样进行复杂推理和问题解决&#xff0c;一直是核心挑战。近年来&#xff0c;思维链&#xff08;Chain-of-Thought, CoT&#xff09;、推理与行动&#xff08;ReAct&#xff09; 和 思维树&#xff08;Tree-of-Thoughts, ToT&#x…

2025时序数据库选型:深入解析IoTDB从主从架构基因到AI赋能的创新之路

原创经验总结,拒绝空谈,用数据和实战说话 时序数据时代的"四重考验" 在智慧工厂、新能源车、金融市场等场景中,每秒百万级的数据点如潮水般涌来。这些时序数据背后隐藏着四大核心挑战:极高的写入并发、强时间关联性查询、海量数据生命周期管理,以及乱序与高基…

深入浅出LVS负载均衡群集:原理、分类与NAT模式实战部署

深入浅出LVS负载均衡群集&#xff1a;原理、分类与NAT模式实战部署 文章目录深入浅出LVS负载均衡群集&#xff1a;原理、分类与NAT模式实战部署一、企业群集&#xff1a;从单台服务器到分布式架构的必然选择1. 什么是群集&#xff1f;2. 为什么需要群集&#xff1f;二、企业群集…

Flash Table实测:JAI赋能低代码开发,重塑企业级应用构建范式

目录&#x1f50d; 引言1.1 什么是Flash Table1.2 低代码平台的进化与FlashTable的革新✨FlashTable背景&#xff1a;为什么需要新一代低代码平台&#xff1f;2.1 传统开发的痛点2.2 低代码平台的局限2.3 FlashTable的差异化定位&#x1f4bb; FlashTable安装&#xff1a;Docke…

SonarQube代码质量管理平台本地化搭建和使用

SonarQube 是一个开源的代码质量管理平台&#xff0c;主要用于持续检查代码质量&#xff0c;支持多种编程语言。 本文章记录了在windows环境中&#xff0c;搭建和使用SonarQube的完整过程。 ①SonarQube平台搭建 SonarQube最新社区版本下载地址&#xff1a; https://www.son…

基于双向LSTM深度学习网络模型的文本序列推荐系统matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.部分程序 4.算法理论概述 5.完整程序 1.程序功能描述 在信息爆炸的时代&#xff0c;用户面临着海量文本信息的筛选难题&#xff0c;文本序列推荐系统应运而生。双向长短期记忆网络&#xff08;Bi-directional Long …

Transformer实战(17)——微调Transformer语言模型进行多标签文本分类

Transformer实战(17)——微调Transformer语言模型进行多标签文本分类 0. 前言 1. 多标签文本分类 2. 数据加载与处理 3. 模型微调 小结 系列链接 0. 前言 与单标签分类不同,多标签分类要求模型能够为同一文本分配多个相关标签,这在新闻分类、文献标注、内容推荐等场景中尤…

开源 C++ QT Widget 开发(十六)程序发布

文章的目的为了记录使用C 进行QT Widget 开发学习的经历。临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 C QT Widget 开发&#xff08;一&#xff09;工程文件结构-CSDN博客 开源…

MATLAB2-结构化编程和自定义函数-台大郭彦甫视频

目录 if elseif else switch case otherwise while exercise练习 for 预宣告 练习题 break tips编程的小技巧 functions函数 练习题 函数句柄 if elseif else 如果condition为真&#xff0c;执行语句 if condition1statement1 elseif condition2statement2 elsest…

LVGL移植2048小游戏全攻略

目录 准备脚手架 修改源码 对接触摸 测试编译 测试运行 这一节将以一个已经编写好的 lvgl 小游戏 2048 描述如何将已经编写完成的 lvgl 程序移植到开发板上。 准备脚手架 在这之前&#xff0c;我们先准备基础的 LVGL 脚手架。可以直接从 lv_g2d_test 里复制过来进行修改…

在Unity2021中使用Profiler的Deep Profile功能时内存超高怎么办?

这通常是因为Deep Profile会记录每一帧所有函数调用的详细信息&#xff0c;导致内存急剧增长&#xff0c;尤其在大型项目或复杂场景中4。别担心&#xff0c;我来帮你分析原因并提供一些解决办法。 理解 Deep Profile 的内存开销与替代方案 Deep Profile是Unity Profiler的一个…

Ubuntu 设置中文输入法

一、使用 IBus&#xff08;Ubuntu 默认框架&#xff09;步骤 1&#xff1a;安装中文输入法sudo apt install ibus-libpinyin ibus-pinyin步骤 2&#xff1a;添加输入法打开 Settings > Keyboard > Input Sources。点击 “”&#xff0c;搜索 Chinese (Intelligent Pinyin…

【Zephyr电源与功耗专题】14_BMS电池管理算法(三重验证机制实现高精度电量估算)

文章目录前言一、算法系统框架设计介绍1.1&#xff1a;核心设计方式1.2&#xff1a;系统架构图1.3&#xff1a;核心参数配置二、核心算法详解2.1&#xff1a;硬件数据采集与滤波2.2&#xff1a;三重算法机制2.2.1&#xff1a;库仑计法&#xff08;电流积分&#xff09;2.2.2&am…

Python网络与多任务编程:TCP/UDP实战指南

Python网络与多任务编程&#xff1a;TCP/UDP实战指南 一、网络编程 1.1 前言 网络编程是现代软件开发中不可或缺的一部分&#xff0c;它使得不同设备之间的数据交换成为可能。Python提供了强大的标准库来支持各种网络编程需求。 1.1.1 IP地址简介 IP地址是互联网上设备的唯一标…

Android8 binder源码学习分析笔记(四)——ServiceManager启动

前文回顾&#xff1a; Android8 binder源码学习分析笔记&#xff08;三&#xff09;&#xff1a; https://blog.csdn.net/g_i_a_o_giao/article/details/151365630?spm1001.2014.3001.5502 Android8 binder源码学习分析笔记&#xff08;二&#xff09;&#xff1a; https://…