STM32的Sg90舵機

1.舵機到底要的是什么信號?

想象舵機就像一個“聽秒表的工人”:

這個工人每隔 20ms 就抬頭看看秒表一次。

秒表上的 高電平持續多久,他就把這個時間當成“指令角度”。

高 1ms → 轉到最左(0°)
高 1.5ms → 轉到中間(90°)
高 2ms → 轉到最右(180°)

所以:舵機只關心“脈寬多少微秒”,不關心占空比,也不關心電平是多少次。
它就像在量高電平的時間長度。

為什么舵機用 PWM 控制?

舵機的內部

常見 3 線舵機(信號、VCC、電源地)內部是:電機 + 減速齒輪 + 電位器反饋 + 控制器。
外部只給它一個周期固定、脈寬可變的控制脈沖,舵機內部會把“脈寬”當作目標角度,做閉環去轉到位。

舵機“吃”的信號

幀周期:通常 20 ms(50 Hz)最通用;很多舵機允許 40–300 Hz,數字舵機還能更高,但50 Hz 是最安全默認。

脈寬:常見 1.0 ms ≈ 0°、1.5 ms ≈ 90°、2.0 ms ≈ 180°(具體要以舵機說明書/實測為準;有些是 0.5–2.5 ms)。

注意:這是“定周期的脈寬控制”,不是單純追求占空比。我們用定時器 PWM 正是為了精準到微秒地生成這個脈寬。

為什么用 PWM?

PWM(脈寬調制)就是 MCU 內部“定時器”自動幫我們生成一個方波信號:

周期固定:20ms 一次。

高電平可調:可以是 1000us、1500us、2000us……

不用自己 while(1) 里 delay 搞波形,定時器硬件自動輸出,非常精準。

所以我們用 定時器 + PWM 模式,就是為了讓 MCU 硬件替我們“定點報時”。

2.在 STM32 里怎么做?

MCU 的“定時器”就像一個秒表:

PSC(預分頻器):決定秒表走得快還是慢。

ARR(自動重裝載):決定多少數后清零 → 就是周期。

CCR(比較寄存器):決定在哪個數的時候翻轉電平 → 就是脈寬。

舉例(假設 STM32 主頻 72MHz):

讓秒表每 1 微秒加 1(PSC=71)。

設置 ARR=20000 → 秒表數到 20000 就清零 → 周期 20ms。

設置 CCR=1500 → 秒表數到 1500 的時候輸出翻轉 → 高電平 1.5ms。

這樣我們就得到了一個“周期 20ms、高電平 1.5ms”的 PWM,舵機看到它,就會乖乖轉到 90°。

把角度變成脈寬

角度和脈寬是線性映射:
脈寬(us)=1000+(角度/180)×(2000?1000),比如:

0° → 1000us

90° → 1500us

180° → 2000us

所以我們只要給定一個角度,就能算出對應的脈寬,然后設置到 CCR 寄存器。

為什么必須這樣做?

因為舵機內部的電路就是按照“高電平時間長度”來解碼的。
如果你給它隨便一個 PWM(比如頻率 1kHz,占空比 10%),它根本不懂,會亂抖。
只有20ms 周期 + 特定的脈寬,舵機才能正確理解。

舉個直觀的比喻

想象你和舵機在玩手電筒信號:每 20 秒我都給你亮一次手電筒。如果亮 1 秒,你就走到左邊。如果亮 1.5 秒,你就走到中間。如果亮 2 秒,你就走到右邊。舵機就是這么傻,但很穩定。

3.舉例具體代碼案例

主函數 main.c

OLED_Init();       // 初始化 OLED 顯示屏
Servo_Init();      // 初始化舵機(其實就是初始化 PWM)
Key_Init();        // 初始化按鍵OLED_ShowString(1,1,"Angle:");while (1)
{KeyNum = Key_GetNum();  // 讀按鍵if(KeyNum == 1){Angle += 30;        // 每按一下 +30°if(Angle > 180){Angle = 0;      // 超過180°回到0°}}Servo_SetAngle(Angle);               // 把角度換成 PWM 脈寬OLED_ShowNum(1, 7, Angle, 3);        // 顯示角度
}

按一次按鍵 → Angle += 30 → Servo_SetAngle(Angle) → 改 PWM 脈寬 → 舵機轉動。

PWM_Init()

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 復用推挽輸出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;       // TIM2_CH2 -> PA1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

STM32 主頻 72 MHz

PSC=72-1 → 72 分頻 → 定時器時鐘 = 1 MHz(1 tick = 1us)

ARR=20000-1 → 每數到 20000 清零 → 周期 = 20000us = 20ms?20ms 就是舵機需要的 PWM 周期。

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   // PWM1 模式
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;                  // CCR 初值
TIM_OC2Init(TIM2, &TIM_OCInitStructure);

輸出 PWM1 模式:計數器 < CCR → 高電平

計數器 ≥ CCR → 低電平

這樣一來,高電平的長度就取決于 CCR。

PWM_SetCompare2()

void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2, Compare);
}

直接改 CCR2,控制高電平時間。

比如 Compare=1500 → 高電平 1500us → 舵機轉到 90°。

Servo_SetAngle()

void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle/180.0f*2000 + 500);
}

把角度(0°~180°)映射到脈寬:

Angle=0 → CCR=500 → 500us

Angle=180 → CCR=2500 → 2500us

這就是一個 500~2500us 的范圍。
(有些舵機要求 1000~2000us,我這里用了 500~2500us,表示支持的角度范圍更大,實際可能會超出舵機物理限制,要注意一下)。

總結一下

參數/函數作用對應舵機需求
PSC=72-1定時器分頻,得到 1MHz 計數頻率1 tick = 1us
ARR=20000-1自動重裝載,周期 20000us20ms 周期
CCR2捕獲比較寄存器控制高電平時間(us)
PWM1 模式輸出模式高電平持續到 CCR,符合舵機信號
Servo_SetAngle()角度→脈寬換算0°=500us,180°=2500us
PA1 (TIM2_CH2)PWM 輸出引腳信號送到舵機

4.注意:普通舵機(角度型) vs 連續旋轉舵機(360°型)

特性普通舵機(角度舵機)連續旋轉舵機(360°舵機)
控制信號周期20ms(50Hz)20ms(50Hz)
PWM脈寬含義表示目標角度表示旋轉方向和速度
典型控制范圍0.5ms ~ 2.5ms ≈ 0°~180°1.0ms ~ 2.0ms = 速度控制(1.5ms停止)
1.0ms信號接近 0°位置反轉(中速)
1.5ms信號中間角度(≈90°)停止
2.0ms信號接近 180°位置正轉(中速)
反饋機制內部電位器 → 有角度反饋無反饋,類似直流電機
能否定位可以,轉到角度后會自動停不可以,只能連續旋轉
控制目標絕對角度轉速 + 方向
主要用途機械臂、云臺、模型舵面小車驅動輪、電機替代
代碼實現公式PWM = (Angle/180)*2000 + 500PWM = 1500 + speed*5(speed=-100~100)

具體連續旋轉舵機,之后會詳細說明(這邊可以留意一下)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94400.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94400.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94400.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

動態帶寬擴展(DBE):下一代Wi-Fi性能提升的關鍵技術

動態帶寬擴展(DBE):下一代Wi-Fi性能提升的關鍵技術 引言 在無線通信技術快速發展的今天,用戶對網絡帶寬和傳輸速率的需求呈指數級增長。為了滿足這種需求,IEEE 802.11標準不斷演進,引入了多項創新技術。其中,動態帶寬擴展(Dynamic Bandwidth Expansion, DBE) 作為80…

Seaborn數據可視化實戰:Seaborn數據可視化基礎-從內置數據集到外部數據集的應用

Seaborn數據集探索與圖表繪制實踐 學習目標 通過本課程&#xff0c;你將學習如何使用Seaborn庫中的內置數據集&#xff0c;了解如何加載這些數據集&#xff0c;并掌握使用這些數據集繪制圖表的基本方法。此外&#xff0c;你還將學習如何導入外部數據集&#xff0c;并在Seaborn中…

漫談《數字圖像處理》之經典空域邊緣檢測Canny與LOG

在《數字圖像處理》的圖像分割領域&#xff0c;Canny 邊緣檢測與 LOG&#xff08;高斯拉普拉斯&#xff09;邊緣檢測是兩款極具代表性的先進空域算法。不同于深度學習驅動的方法&#xff0c;它們通過對圖像像素的直接計算提取邊緣&#xff0c;下面用更貼近日常認知的語言&#…

搶紅包案例加強版

加join的功能是保證線程全部運行完畢&#xff0c;之后好統計構造器剛開始為空列表&#xff0c;利用這個方法返回每個成員列表&#xff08;把每個員工弄成一個列表里面寫他們搶到的紅包大小&#xff0c;索引代表搶到的個數。&#xff09;

曲面方程的三維可視化:從數學解析到Python實現

在三維幾何建模中,我們經常遇到需要將隱式方程可視化的需求。本文將深入探討一個特定的曲面方程: XH?YH2+ZH2tan?(θ)?H2πarcsin?(YHYH2+ZH2)=0 X_H - \frac{\sqrt{Y_H^2 + Z_H^2}}{\tan(\theta)} - \frac{H}{2\pi} \arcsin\left( \frac{Y_H}{\sqrt{Y_H^2 + Z_H^2}} \r…

當GitHub宕機時,我們如何協作

引言簡述GitHub在全球開發協作中的重要性提出假設性問題&#xff1a;當GitHub不可用時&#xff0c;如何確保團隊協作不中斷常見的GitHub宕機場景服務完全不可用&#xff08;如DNS問題、全球性故障&#xff09;部分功能受限&#xff08;如API速率限制、倉庫訪問失敗&#xff09;…

如何確定哪些層應添加適配器(Adapter)?(58)

“它如何確定哪些層應添加適配器(Adapter)?是否只有量化層符合條件?我能否也將適配器添加到常規(非量化)線性層上?” 這個問題提得很好,我會逐一為你解答。首先,先給出簡潔結論: ? 主流模型架構會預配置目標層列表,適配器將應用于這些列表中的層。 ? 無論目標層…

【內網滲透】CVE-2025-21420 利用cleanmgr本地提權

目錄 原理 POC 復現 一個windows本地提權漏洞 這是一個存在于Windows磁盤清理工具&#xff08;cleanmgr.exe&#xff09;中的權限提升漏洞。攻擊者可以利用該系統組件在處理特定目錄時的邏輯缺陷&#xff0c;通過精心構造的符號鏈接&#xff08;Symbolic Link&#xff09;&a…

什么是JSON-RPC 2.0,在項目中應該怎么使用

它是什么 JSON-RPC 2.0 是一種超輕量、與傳輸無關的遠程調用協議&#xff1a;用 JSON 表達“方法名 參數 → 結果/錯誤”。可跑在 HTTP、WebSocket、Unix 管道&#xff0c;甚至 stdio 上&#xff08;很多開發協議如 LSP 就用它&#xff09;。 報文長這樣 ? 請求&#xff1a; …

基于CentOS7:Linux服務器的初始化流程

文章目錄前言一、服務器初始化1.1 配置國內 Yum 源&#xff08;加速軟件安裝&#xff09;1.1.1 使用阿里云源1.1.2 使用清華源&#xff08;可選&#xff09;1.2 更新系統與安裝必備工具1.3 網絡連接驗證1.4 配置主機名1.5 同步時間1.6 配置iptables防火墻1.6.1 手動配置iptable…

如何避免MyBatis二級緩存中的臟讀

避免 MyBatis 二級緩存中的臟讀問題&#xff08;即緩存數據與數據庫實際數據不一致&#xff09;&#xff0c;需要從緩存更新機制、配置策略、業務設計等多維度入手。以下是經過實踐驗證的解決方案&#xff0c;結合底層原理和具體實現&#xff1a;一、理解二級緩存臟讀的根源臟讀…

Python實現RANSAC進行點云直線、平面、曲面、圓、球體和圓柱擬合

本節我們分享使用RANSAC算法進行點云的擬合。RANSAC算法是什么&#xff1f;不知道的同學們前排罰站&#xff01;(前面有)總的來說&#xff0c;RANSAC&#xff08;Random Sample Consensus&#xff09;是一種通用的迭代魯棒估計框架&#xff0c;無論擬合何種幾何模型&#xff0c…

實驗2 天氣預報

實驗1 天氣預報一、實驗目標二、實驗步驟&#xff08;一&#xff09;準備工作&#xff08;二&#xff09;小程序開發項目創建頁面配置視圖設計邏輯實現三、程序運行結果四、問題總結與體會主要問題及解決方案主要收獲chunk的博客地址一、實驗目標 1、掌握服務器域名配置和臨時…

【CVE-2025-5419】(內附EXP) Google Chrome 越界讀寫漏洞【內附EXP】

前言 近日,奇安信CERT監測到Google Chrome中曝出一枚高危安全漏洞(CVE-2025-5419,QVD-2025-21836),該漏洞屬于越界讀寫問題,攻擊者只需通過構造惡意網頁,就可能觸發漏洞,從而繞過Chrome的沙箱防護,直接實現遠程代碼執行,最終完全控制用戶設備。目前,安全社區已確認…

【科研繪圖系列】R語言在海洋生態學中的應用:浮游植物糖類組成與溶解性有機碳的關系

禁止商業或二改轉載,僅供自學使用,侵權必究,如需截取部分內容請后臺聯系作者! 文章目錄 介紹 數據準備 數據處理 糖類組成隨年齡的變化 糖類組成與DOC含量的關系 數據可視化 加載R包 數據下載 導入數據 數據預處理 畫圖 總結 系統信息 介紹 本教材通過R語言及其強大的數據…

webpack文件指紋:hash、chunkhash與contenthash詳解

文件指紋就是打包后輸出文件的后綴&#xff0c;每次構建都會生成不同的文件后綴&#xff0c;這樣可以防止瀏覽器的默認緩存&#xff0c;使客戶端代碼可以及時修改。文件指紋的三種方式&#xff1a;? hash ?&#xff1a;基于整個項目構建內容生成全局哈希值&#xff0c;任何文…

Pytest 插件怎么寫:從0開發一個你自己的插件

概述 你用過 pytest-html 生成報告,或用 pytest-xdist 并行運行測試嗎?這些強大的功能,其實都是 Pytest 插件 這些都是我們引入項目后直接使用的,當然 你也可以自己寫一個 Pytest 插件 基本原理 Pytest 的強大,源于它的 插件系統。它允許你通過定義特定的函數(稱為 H…

Java:IO流——基礎篇

目錄 前言 一、File 類 1、概述 ①構造方法 ②實例對象 2、使用 ①查看名稱、路徑、長度 ②判斷、創建和刪除操作 ③目錄遍歷操作 二、IO流 1、流的概念 2、流的分類 ①按數據流向 ②按數據類型 ③按功能 3、字節流 ⑴FileInputStream——文件輸入流 ⑵FileOutputStream——文件…

數據挖掘 5.1~5.2 PCA——前言

5.1 Twelve ways to fool the masses 5.1 愚弄大眾的十二種方法 5.2.1 Prelim: Old MacDonald meets Lagrange 5.2.1 前言&#xff1a;老麥克唐納遇見拉格朗日 5.2. Prelim: Meet stubborn vectors 5.2. 前言&#xff1a;遇見頑固向量 5.2.3 Prelim: Covariance and its friend…

DeepSeek分析

(非走向數字時代,融入數字生活,構建數字生態的分解,只是感覺可以分享給大家---因此現設置VIP,旺海涵) 這是deepseek剛爆的時候,春節緊急對其做的分析。 內容還是私藏狀態,做了初步評估,感覺可以分享給大家!!! 但是非共享的構建數字生態的核心,因此添加了vip設置…