伺服馬達(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++;}
}
