伺服馬達(servo motor)其組成包含直流馬達、減速齒輪、電位器及控制電路,減速齒輪可以減緩馬達轉速同時提高轉矩,而電位器是用來回饋目前位置。當我們輸入一脈衝訊號後,控制電會路判斷目標角度與電位器之間有差異而轉動馬達,此時馬達轉動會同時帶動電位器變動,當控制電路判斷電位器回饋的電壓與目標角度位置相同時,即停止轉動,如此即能達到角度控制。
Type:SG90
Weight: 9g
Dimension: 23*12.2*29mm
Stall torque: 1.8kg/cm(4.8V)
Operating speed: 0.1sec/60degree(4.8v)
Operating voltage: 4.8V
Temperature range: 0℃-55℃
Pulse Cycle: 20ms
Pulse Width: 0.5ms-2.0ms
Dead band width: 10us
手邊目前得到的一顆伺服馬達型號為SG90,它的控制方式是輸入一頻率在50Hz(20ms)的脈衝訊號,高電位的寬度需介於0.5ms~2.0ms之間,因此0.5ms可視為負90度,2.0ms可視為正90度,另外要注意的是,它的死區為10us,若角度控制兩個訊號的高電位寬度差異小於10us,馬達即不會有任何變動。
本文採用STC 12C5A60S2的單晶片做為驅動控制,振盪頻率為12Mhz,由於此晶片可以設為1T模式,即一個指另只需要一個機械週期即能完成,因此1T=1/12000000=0.083us
1.首先我們先推算0.5ms-2.0ms之間產生180個角度變話所需的最小脈衝寬度
(2.0ms-0.5ms)/180=0.0083ms
2.利用計時器產生<0.0083ms的中斷
TH=0.0083ms/0.083us=100
實際量測TH=100時,中斷時間為9.4us,因此修正TH=80。
3.死區為10us,控制1度最小為8.3us,因此當兩個角度命令差異等於1時,需+1(正轉)或-1(反轉)。
4.實際應用需再調整,本文所使用的伺服馬達角度在-90度時為0.48ms,在90度時為1.94ms。
#include "STC12C5A.H" #define FOSC 12000000L #define MODE1T //宣告為1T MCU #ifdef MODE1T #define CT 1 //1T指令所需週期 #else #define CT 12 //12T指令所需週期 #endif typedef unsigned char uchar; typedef unsigned int uint; uint i,j,k,PCI=0; #define tm0_count 150000 void servo(uint svcount); void main() { #ifdef MODE1T AUXR=0x80; //設為1T模式 #endif TMOD=0x01; //設定Timer0 為16bit計數器 TH0=(65536-FOSC/CT/tm0_count)/256; TL0=(65536-FOSC/CT/tm0_count)%256; TR0=1; //啟動Timer0計數器 ET0=1; EA=1; P1=0; PCI=1; while(1) { if(j<=50) servo(56); //-90度 else if(j>50&&j<=100) servo(227); //90度 else j=0; } } void tm0_isr() { TH0=(65536-FOSC/CT/tm0_count)/256; TL0=(65536-FOSC/CT/tm0_count)%256; i++; } void servo(uint svcount) { if((i>=svcount)&&(i<2330)){P1=0x00;} else if(i>=2330){P1=0xff; i=0;j++;} }