從0°到180°,STM32玩轉MG996R舵機

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://…