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