一、前言
本文介紹如何通過(guò)51單片機(jī)控制SG90舵機(jī)實(shí)現(xiàn)角度的正反轉(zhuǎn)轉(zhuǎn)動(dòng)。SG90舵機(jī)是一種常用的微型舵機(jī),具有體積小、重量輕、結(jié)構(gòu)簡(jiǎn)單等特點(diǎn),被廣泛應(yīng)用于機(jī)器人、遙控模型和各種自動(dòng)控制系統(tǒng)中。
使用51單片機(jī)(STC89C52)作為控制器,利用其強(qiáng)大的IO口和定時(shí)器功能來(lái)實(shí)現(xiàn)對(duì)SG90舵機(jī)的控制。通過(guò)編程控制,可以精確地控制舵機(jī)按指定的角度進(jìn)行正轉(zhuǎn)或反轉(zhuǎn)運(yùn)動(dòng)。
舵機(jī)的控制是通過(guò)脈沖寬度調(diào)制(PWM)來(lái)實(shí)現(xiàn)的。在控制舵機(jī)時(shí),需要向舵機(jī)發(fā)送一系列的脈沖信號(hào),脈沖的寬度決定了舵機(jī)的角度位置。通常情況下,SG90舵機(jī)的控制脈沖周期為20毫秒,脈沖寬度在0.5毫秒到2.5毫秒之間,對(duì)應(yīng)的角度范圍為0度到180度。
為了實(shí)現(xiàn)舵機(jī)的正反轉(zhuǎn)轉(zhuǎn)動(dòng),需要控制脈沖的寬度在不同的范圍內(nèi),以達(dá)到不同的角度位置。通過(guò)調(diào)整脈沖的寬度和周期,我們可以控制舵機(jī)按照我們的要求進(jìn)行旋轉(zhuǎn)。
下面將介紹如何通過(guò)51單片機(jī)的IO口和定時(shí)器來(lái)生成適用于SG90舵機(jī)的PWM信號(hào)。編寫(xiě)相應(yīng)的程序,通過(guò)調(diào)整脈沖寬度來(lái)實(shí)現(xiàn)舵機(jī)的正反轉(zhuǎn)轉(zhuǎn)動(dòng),并提供示例代碼。
二、SG90電機(jī)介紹
SG90電機(jī)是一種微型舵機(jī),常用于模型、機(jī)器人和其他小型機(jī)械裝置中。
1. 工作原理: SG90電機(jī)基于直流電機(jī)的原理,通過(guò)PWM(脈寬調(diào)制)信號(hào)控制舵機(jī)轉(zhuǎn)動(dòng)角度。它由一個(gè)電機(jī)、減速齒輪組和一個(gè)位置反饋電路組成。該反饋電路使用了一個(gè)電位器來(lái)檢測(cè)舵機(jī)的當(dāng)前位置并將其反饋給控制電路。
2. 特點(diǎn):
- 尺寸小巧:SG90電機(jī)非常小巧,體積輕盈,適合于空間有限的應(yīng)用。
- 轉(zhuǎn)動(dòng)角度范圍廣:通常情況下,SG90電機(jī)可以轉(zhuǎn)動(dòng)約180度左右,但具體轉(zhuǎn)動(dòng)范圍可以通過(guò)控制信號(hào)調(diào)整。
- 高精度:SG90電機(jī)具有較高的轉(zhuǎn)動(dòng)精度和穩(wěn)定性,適用于需要精確控制的應(yīng)用。
- 低功耗:SG90電機(jī)功耗較低,可以在低電壓下工作。
- 相對(duì)經(jīng)濟(jì):相比大型舵機(jī)或步進(jìn)電機(jī),SG90電機(jī)價(jià)格相對(duì)較低,適合在預(yù)算有限的項(xiàng)目中使用。
3. 控制方式: 控制SG90電機(jī)需要提供PWM信號(hào)。以下是控制SG90電機(jī)的基本步驟:
- 將SG90電機(jī)的VCC引腳連接到正電源(通常為5V),將GND引腳連接到地。
- 將信號(hào)線(例如,控制舵機(jī)角度的引腳)連接到微控制器或其他控制設(shè)備的數(shù)字輸出引腳。
- 在控制設(shè)備上設(shè)置指定的PWM輸出引腳,并使用相應(yīng)的編程語(yǔ)言或庫(kù)發(fā)送PWM信號(hào)。PWM的工作周期通常為20ms,并且脈寬的范圍可以在0.5ms到2.5ms之間調(diào)整。
- 根據(jù)所發(fā)送的PWM信號(hào),SG90電機(jī)會(huì)轉(zhuǎn)動(dòng)到相應(yīng)的角度位置。一般來(lái)說(shuō),0.5ms的脈寬對(duì)應(yīng)最左端角度,2.5ms的脈寬對(duì)應(yīng)最右端角度,1.5ms的脈寬對(duì)應(yīng)中間位置。具體的脈寬范圍和對(duì)應(yīng)的角度可以根據(jù)電機(jī)型號(hào)和要求進(jìn)行調(diào)整。
SG90電機(jī)的額定工作電壓為4.8V-6V,超過(guò)這個(gè)范圍可能會(huì)損壞電機(jī)。舵機(jī)在運(yùn)行時(shí)會(huì)產(chǎn)生一定的電流峰值,在使用時(shí)應(yīng)確保電源能夠提供足夠的電流。
三、實(shí)現(xiàn)代碼
3.1 正反轉(zhuǎn)實(shí)現(xiàn)-模擬延時(shí)
以下是通過(guò)51單片機(jī)控制SG90舵機(jī)按角度正反轉(zhuǎn)轉(zhuǎn)動(dòng)的實(shí)現(xiàn)代碼,封裝子函數(shù)調(diào)用:
#include <reg51.h>
// 定義IO口連接舵機(jī)的引腳
sbit servoPin = P1^0;
// 延時(shí)函數(shù)
void delay(unsigned int time) {
unsigned int i, j;
for(i = 0; i < time; i++) {
for(j = 0; j < 1000; j++);
}
}
// 控制舵機(jī)按指定角度進(jìn)行正轉(zhuǎn)
void rotateClockwise(unsigned int angle) {
unsigned int pulseWidth = 500 + angle * 11.11;
unsigned int i;
for(i = 0; i < 50; i++) {
servoPin = 1; // 輸出高電平
delay(pulseWidth);
servoPin = 0; // 輸出低電平
delay(20000 - pulseWidth);
}
}
// 控制舵機(jī)按指定角度進(jìn)行反轉(zhuǎn)
void rotateCounterclockwise(unsigned int angle) {
unsigned int pulseWidth = 2500 - angle * 11.11;
unsigned int i;
for(i = 0; i < 50; i++) {
servoPin = 1; // 輸出高電平
delay(pulseWidth);
servoPin = 0; // 輸出低電平
delay(20000 - pulseWidth);
}
}
void main() {
while(1) {
// 正轉(zhuǎn)90度
rotateClockwise(90);
delay(2000); // 停留2秒
// 反轉(zhuǎn)90度
rotateCounterclockwise(90);
delay(2000); // 停留2秒
}
}
3.2 正反轉(zhuǎn)角度控制-PWM控制
下面是使用STC89C52的定時(shí)器0和GPIO口來(lái)模擬產(chǎn)生PWM信號(hào)的實(shí)現(xiàn)代碼:
#include <reg52.h>
#define FREQ_OSC 11059200UL // 單片機(jī)工作頻率
#define PWM_FREQ 50 // PWM信號(hào)頻率
#define PWM_RESOLUTION 100 // PWM信號(hào)分辨率
sbit Servo = P1^0; // SG90舵機(jī)控制引腳
unsigned int pwmWidth = 0; // PWM脈寬
// 定時(shí)器0初始化函數(shù)
void Timer0Init() {
EA = 0; // 關(guān)閉總中斷
TMOD &= 0xF0; // 清除T0控制位
TMOD |= 0x01; // 設(shè)置T0為工作方式1(16位定時(shí)器)
TH0 = (65536 - (FREQ_OSC / 12 / PWM_FREQ)) / 256; // 計(jì)算并設(shè)置初始計(jì)數(shù)值高8位
TL0 = (65536 - (FREQ_OSC / 12 / PWM_FREQ)) % 256; // 計(jì)算并設(shè)置初始計(jì)數(shù)值低8位
TR0 = 1; // 啟動(dòng)定時(shí)器0
ET0 = 1; // 允許定時(shí)器0中斷
EA = 1; // 開(kāi)啟總中斷
}
// 定時(shí)器0中斷服務(wù)函數(shù)
void Timer0Interrupt() interrupt 1 {
if (pwmWidth > PWM_RESOLUTION) {
Servo = 0; // 舵機(jī)復(fù)位
} else {
Servo = 1; // 舵機(jī)置位
}
TH0 = (65536 - (FREQ_OSC / 12 / PWM_FREQ)) / 256; // 重新設(shè)置計(jì)數(shù)值高8位
TL0 = (65536 - (FREQ_OSC / 12 / PWM_FREQ)) % 256; // 重新設(shè)置計(jì)數(shù)值低8位
pwmWidth++; // 每次中斷增加PWM脈寬
}
// 主函數(shù)
void main() {
Timer0Init(); // 初始化定時(shí)器0
while (1) {
if (pwmWidth > PWM_RESOLUTION) {
pwmWidth = 0;
}
}
}
代碼中,使用P1^0引腳作為SG90舵機(jī)的控制引腳,并通過(guò)定時(shí)器0來(lái)產(chǎn)生PWM信號(hào)。
在Timer0Init函數(shù)中,設(shè)置定時(shí)器0為16位定時(shí)器工作方式1,計(jì)算并設(shè)置初始計(jì)數(shù)值,啟動(dòng)定時(shí)器0,并允許定時(shí)器0中斷。
在Timer0Interrupt函數(shù)中,每次定時(shí)器0中斷時(shí)調(diào)整舵機(jī)控制引腳的電平狀態(tài),并更新定時(shí)器0的計(jì)數(shù)值。
在主函數(shù)中,循環(huán)檢測(cè)PWM脈寬是否達(dá)到設(shè)定的分辨率,如果超過(guò)則重新從0開(kāi)始計(jì)數(shù)。