調試了幾天的舵機今天終于可以受我控制了,把學習到得知識和大家分享一下。對遇到的問題期待和大家一起討論。
下面和大家分享一下有關舵機的資料(資料來源于天祥電子)。
1、舵機實物圖片
2、舵機介紹
舵機英文叫Servo,也稱伺服機。其特點是結構緊湊、易安裝調試、控制簡單、大扭力、成本較低等。舵機的主要性能取決于最大力矩和工作速度(一般是以秒 /60°為單位)。它是一種位置伺服的驅動器,適用于那些需要角度不斷變化并能夠保持的控制系統(tǒng)。在機器人機電控制系統(tǒng)中,舵機控制效果是性能的重要影響因素。舵機能夠在微機電系統(tǒng)和航模中作為基本的輸出執(zhí)行機構,其簡單的控制和輸出使得單片機系統(tǒng)很容易與之接口。
3、舵機的工作原理
標準的舵機有3條引線,分別是:電源線Vcc、地線GND和控制信號線,如圖3所示。
圖3 標準舵機引線示意圖
在航模遙控系統(tǒng)中,控制信號由接收機的通道進入信號調制芯片,獲得直流偏置電壓。他內部有一個基準電路,產生周期為20ms,寬度為1.5ms的基準信號,將獲得的直流偏置電壓和電位器的電壓比較,獲得電壓差輸出。最后,電壓差的正負輸出到電機驅動芯片決定電機的正反轉。當電機轉速一定時,通過級聯(lián)減速齒輪帶動電位器旋轉,使得電壓差為0,電機停止轉動。其實我們可以不用去了解它內部的具體工作原理,知道它的控制原理就夠了。就象我們使用三極管一樣,知道可以拿它來做開關管或放大管就行了,至于管內的電子具體怎么流動是可以完全不用去考慮的。舵機的控制信號也是PWM信號,利用占空比的變化改變舵機的位置。圖4為舵機輸出轉角與輸入信號脈沖寬度的關系,其脈沖寬度在0.5~2.5ms之間變化時,舵機輸出軸轉角在0°~180°之間變化。
圖4 舵機輸出轉角與輸入信號脈沖寬度的關系
4、用單片機實現(xiàn)舵機轉角控制
單片機系統(tǒng)實現(xiàn)對舵機輸出轉角的控制,必須首先完成兩個任務:首先是產生基本的PWM周期信號,即產生20ms的周期信號;其次是脈寬的調整,即單片機調節(jié)PWM信號的占空比。
單片機作為舵機的控制部分,能使PWM信號的脈沖寬度實現(xiàn)微秒級的變化,從而提高舵機的轉角精度。單片機完成控制算法,再將計算結果轉化為PWM信號輸出到舵機,由于單片機系統(tǒng)是個數(shù)字系統(tǒng),其控制信號的變化完全依靠硬件計數(shù),所以受外界干擾較小,整個系統(tǒng)工作可靠。
單片機控制單個舵機是比較簡單的,利用一個定時器即可,假設僅控制舵機5個角度轉動,其控制思路如下:只利用一個定時器T0,定時時間為0.5ms,定義一個角度標識,數(shù)值可以為1、2、3、4、5,實現(xiàn)0.5ms、1ms、1.5ms、2ms、2.5ms高電平的輸出,再定義一個變量,數(shù)值最大為40,實現(xiàn)周期為20ms。每次進入定時中斷,判斷此時的角度標識,進行相應的操作。比如此時為5,則進入的前5次中斷期間,信號輸出為高電平,即為2.5ms的高電平。剩下的35次中斷期間,信號輸出為低電平,即為17.5ms的低電平。這樣總的時間是20ms,為一個周期。
當用單片機系統(tǒng)控制多個舵機工作時,可以參考下以方法:以驅動8路舵機為例,假設使用的舵機工作周期均為20ms時,那么用單片機定時器產生的多路PWM波的周期也相同。使用單片機的內部定時器產生脈沖計數(shù),一般來說,舵機工作正脈沖寬度小于周期的1/8,這樣能夠在1個周期內分時啟動各路PWM波的上升沿,再利用定時器中斷T0確定各路PWM波的輸出寬度,定時器中斷T1控制20ms的基準時間。第1次定時器中斷T0按20ms的1/8配置初值,并配置輸出I/O口,第1次T0定時中斷響應后,將當前輸出I/O口對應的引腳輸出置高電平,配置該路輸出正脈沖寬度,并啟動第2次定時器中斷,輸出I/O口指向下一個輸出口。第2次定時器定時時間結束后,將當前輸出引腳置低電平,配置此中斷周期為20ms的1/8減去正脈沖的時間,此路PWM信號在該周期中輸出完畢,往復輸出。在每次循環(huán)的第16次(2×8=16)中斷實行關定時中斷T0的操作,最后就能夠實現(xiàn)8路舵機控制信號的輸出。
5、舵機與單片機連接原理圖
在用單片機驅動舵機之前,要先確定相應舵機的功率,然后選擇足夠功率的電源為舵機供電,控制端無需大電流,直接用單片機的I/O口就可操作,擴展板上舵機信號線接單片機的P1.7,舵機與單片機連接原理圖如圖5所示。
圖5 舵機和單片機連接原理圖
根據我的調試經驗,選擇足夠功率的電源為舵機供電是非常重要的,開始時我用單片機學習板調試,用示波器觀察了輸出地波形、占空比和脈寬都和資料里提到的完全一樣,但是舵機轉動的就是不正常,有的時候吱吱的轉不動,有時候只是轉向一邊,怎么也不轉回來。個人覺得,所有問題的根源都在電源上,如果舵機供電正常,應該沒有什么問題。
以下是我測試舵機的C語言代碼,參考至網絡。
#include
#define uint unsigned int
#define uchar unsigned char
uint j,a,num=2;
uchar pro;
uchar tab[]={10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,28,28,
25,24,30,30,30,20,19,18,17,16,15,14,13,12,11,10};
sbit PWM=P1^0; //舵機pwm//
sbit key1=P1^6;
sbit key2=P1^7;
void init()
{
TMOD=0x01;
EA=1;
TR0=1;
TH0 = 0xff;
TL0 = 0xce;
ET0=1;
}
void delay_us(uint x)
{
do {
x--;
}
while(x>1);
}
void delay_ms(uint x)
{
while(x!=0)
{
delay_us(500);
x--;
}
}
void dj(uint m) //舵機控制
{
pro=m;
}
void main()
{
init();
while(1)
{
// baidong();
if(key1==0)
{
delay_ms(5);
if(key1==0)
{
while(!key1);
num++;
if(num==6)
num=1;
}
}
if(key2==0)
{
delay_ms(5);
if(key2==0)
{
while(!key2);
num--;
if(num==0)
num=6;
}
}
if(num==1)
{
for(a=0;a<10;a++)
{
dj(tab[0]);
}
}
if(num==2)
{
for(a=0;a<10;a++)
{
dj(tab[6]);
}
}
if(num==3) //
{
for(a=0;a<10;a++)
{
dj(tab[9]);
}
}
if(num==4)
{
for(a=0;a<10;a++)
{
dj(tab[12]);
}
}
if(num==5)
{
for(a=0;a<10;a++)
{
dj(tab[15]);
}
}
}
}
void timer0() interrupt 1//定時0.1ms
{
TH0=0xff;
TL0=0xce;
j++;
if(j<=pro)
{
PWM=1;
}
else
{
PWM=0;
}
if(j==400) //周期20ms
{
j=0;
PWM=~PWM;
}
}
希望大家看了本文后能有些小收獲。