關(guān)于舵機,目前網(wǎng)絡(luò)上和書本上,很難找到詳細(xì)可行的資料(如果有,那估計是我眼瞎,不要理我就好啦-
-。,我在制作ROBOTCUP搬運機器人的過程中,由于聽取學(xué)長的“建議”,采用舵機作為機器人的驅(qū)動,加之當(dāng)時太年輕,使用90系列51單片機,所以一個舵機耗了3個月,并沒有按照預(yù)期,參加比賽(這個也真的不怪誰,不走個彎路,也不會對舵機和51單片機有如今的大徹大悟-
-。。所以啊,如果有學(xué)弟學(xué)妹,想要在以后做之類的比賽甚至于從事相關(guān)的工作,那么好好研究下舵機的控制,對你是十分有幫助的(無論是對于舵機控制的原理還是對主控芯片的理解都很有幫助)。關(guān)于舵機的控制,我查詢過相關(guān)的資料,也請教過我的導(dǎo)師,但是結(jié)果都很不滿意,舵機亂轉(zhuǎn),轉(zhuǎn)速控制不精確,出現(xiàn)過各種問題。最終,我也硬是通過砸錢和砸時間(20塊一個的PWM調(diào)制器不知道燒了多少-
-!這個反正燒的不是我的,不心疼,但是90塊一個舵機,加上60塊一個的航模PWM舵機調(diào)制器還是砸了幾百塊進去的),和小伙伴通過實驗,反復(fù)測試得到的結(jié)果,在這里分享出來,希望能幫助到學(xué)弟學(xué)妹。
首先,舵機是做什么的?舵機按照旋轉(zhuǎn)的角度,可以分為180°和360°連續(xù)旋轉(zhuǎn)舵機。180°舵機,顧名思義,就是只能旋轉(zhuǎn)180°的舵機,我們可以通過一定的方法,精確的控制舵機旋轉(zhuǎn)的角度,因此,就我目前接觸到的比賽來看,180°舵機在雙足機器人以及飛思卡爾競速車的轉(zhuǎn)向上使用的很多,雙足機器人就是模仿人走路的機器人,通過控制180°舵機轉(zhuǎn)動的角度,完成指定的動作。飛思卡爾轉(zhuǎn)向類似于汽車使用方向盤轉(zhuǎn)向,舵機就起到方向盤的作用。360°連續(xù)旋轉(zhuǎn)舵機,可以通過一定手段,控制舵機的旋轉(zhuǎn)方向和速度,因此,也常常用于小車型機器人的驅(qū)動上。這里需要說明的是,180°舵機是無法調(diào)速的,就是說,他始終會以最快速度,朝著你設(shè)定的角度旋轉(zhuǎn),直到旋轉(zhuǎn)到目標(biāo)角度停止。而360°舵機是無法控制旋轉(zhuǎn)的角度的,只可以控制轉(zhuǎn)和停,正轉(zhuǎn)和反轉(zhuǎn)以及轉(zhuǎn)速。
下面是舵機:
安裝有180°舵機的雙足機器人:
安裝有360°舵機的搬運機器人:
上一段中,我提到可以通過一定的方法,控制舵機,到底是什么方法?PWM!我也不是什么老教授,我不喜歡說太多抽象的理論,這里,只需要知道,要控制舵機,我們要讓單片機輸出一個周期為20ms-30ms,高電平為0.5ms-2.5ms的信號即可。
關(guān)于硬件上的設(shè)計,無非是保證供電的穩(wěn)定和預(yù)留出PWM的接口,由于我本身也不是做硬件的,這里就不詳細(xì)說明了,這里附上一張圖,感興趣的小伙伴可以研究一下,如果對硬件上有其他的問題,也可以私下聯(lián)系我,我們組做硬件的小伙伴,還是很厲害的。
我這里對360°舵機如果通過51單片機的程序進行控制做詳細(xì)的說明。對于360°舵機而言,PWM高電平為0.5-1.5ms為正轉(zhuǎn)區(qū)間,1.5-2.5ms為反轉(zhuǎn)區(qū)間,1.5ms為舵機剎車點,實際測試過程中,我使用的舵機,高電平0.5ms-1.37ms為以最大速度正轉(zhuǎn),正轉(zhuǎn)的調(diào)速高電平區(qū)間為1.37ms-1.47ms(高電平越靠近1.5ms,舵機轉(zhuǎn)速越慢),高電平1.53ms-2.5ms為以最大速度反轉(zhuǎn),反轉(zhuǎn)調(diào)速高電平區(qū)間為:1.53-1.63ms(高電平越靠近1.5ms,舵機轉(zhuǎn)速越慢),剎車高電平區(qū)間為:1.47-1.53ms。是不是感覺很簡單呢?聽起來好像是挺簡單的,但是有沒有想過如何使用51單片機產(chǎn)生我們需要的PWM呢?有小伙伴會說,用定時器!當(dāng)然,我一開始也是這么想的,看看下面這段程序:
unsigned int
i=1;
int n;
void
ste360(n){
TMOD=0X01;
TL0=0XF6; //
0.01ms
TH0=0XFF;
TR0=1;
EA=1;
ET0=1;
P1=0X00;
while(1);
}
void _pwm () interrupt 1
{
TH0=0xff; //
0.01ms
TL0=0xF6;
i++;
if(i<=n){
P1=0XFF; //
1.37<<1.47-1.54<<1.63
} else
P1=0x00;
if(i>=2000){
i=1;
}
}
看起來程序好像沒有什么問題,ste360(n)這個函數(shù),n就可以控制pwm高電平的時間,我設(shè)定定時器為每0.01ms進入一次中斷,所以,要想得到1.5ms高電平,是不是n填寫150就行了?答案是否定的,至于具體結(jié)果怎么樣,我這里就不截圖了,沒有在學(xué)校沒法用示波器,之后完善吧。我這里告訴你,雖然程序邏輯是沒有問題的,計算出來確實是1.5ms,但是結(jié)果可能是高電平為3ms+,為什么?這個問題困惑了我挺久,我和學(xué)長也討論過,他說,編譯過程中,會將我們寫的c文件,編譯成匯編文件,然后轉(zhuǎn)成機器語言,這個過程中可能會有誤差。而我覺得,晶振本身是有誤差的,其次,這樣反復(fù)的進入中斷,細(xì)小的誤差會被無限的放大。同樣是使用c,stm32上pwm的精度高的離譜。所以,使用51單片機的8位定時器來控制舵機,在我看來,是完全不可行的(可以質(zhì)疑我的能力,但是上面的程序是在我寫的眾多定時器控制pwm輸出程序中早期的一個,放出來理解簡單,但我在很長一段時間里,極力優(yōu)化代碼,嘗試過各種思路,但是結(jié)果只能說有提升,但是遠遠達不到控制舵機的要求),有不怕死的小伙伴,也可以自己寫點小程序,打在示波器上看看。不能用定時器,那怎么辦?又有小伙伴說了,stc12系列的51單片機是自帶8位pwm模塊,是不是可以用12系列的單片機實現(xiàn)?看程序:
#include
//-----------------------------
// 7
6 5 4 | 3 2 1
0
sfr CCON=0xD8;//CF CR -
- | - - CCF1 CCF0
//-----------------------------
//CF:PCA計數(shù)陣列溢出標(biāo)志.計數(shù)值翻轉(zhuǎn)時由硬件置位。
//CR:PCA計數(shù)陣列運行控制位。
//CCF1:PCA模塊1中斷標(biāo)志。當(dāng)出現(xiàn)匹配或者捕獲時由硬件置位。
//CCF0:PCA模塊0中斷標(biāo)志。當(dāng)出現(xiàn)匹配或者捕獲時由硬件置位。
/
sfr
CCAP0L=0xEA;//PCA模塊0的捕捉/比較寄存器低8位
sfr
CCAP0H=0xFA;//PCA模塊0的捕捉/比較寄存器高8位
sfr
CCAPM0=0xDA;//PCA模塊0的工作模式寄存器
//---------------------------------------
//7 6
5 4
3
2 1
0
//- ECMn CAPPn CAPNn MATn T0Gn PWMn
ECCFn
//----------------------------------------
//ECOMn:使能比較器,1時使能比較器功能
//CAPPn:正捕獲,1時使能上升沿捕獲
//CAPNn:負(fù)捕獲,1時使能下降沿捕獲
//MATn:匹配:1時,PCA計數(shù)器的值與模塊的比較/捕獲寄存器的值匹配將置位CCON寄存器中斷標(biāo)志位CCFn
//T0Gn:翻轉(zhuǎn),1時,工作在PCA告訴輸出模式,PCA計數(shù)器的值與模塊的比較/捕獲寄存器的值匹配將是CEXn腳翻轉(zhuǎn)
//PWMn:脈寬調(diào)節(jié)輸出模式,1時,使能CEXn腳用做PWM輸出
//EECFn:使能CCFn中斷,使能寄存器CCON中的捕獲/比較標(biāo)志CCFn,用來產(chǎn)生中斷
sfr
PCA_PWM0=0xF2;//PCA模塊0,PWM寄存器
//-----------------------------------
//
7 6 5 4
3 2 1
0
//PCA_PWMn:- - - - | - -
EPCnH EPCnL
//-----------------------------------
sfr
CCAP1L=0xEB;
sfr
CCAP1H=0xFB;
sfr
CCAPM1=0xDB;
sfr
PCA_PWM1=0xF3;//
sbit
CR=0xDE;//因為只有能和8整除的才能位尋址,所以能些0xDE,看起來有沖突,實際上不會。
sfr AUXR1=0xA2;//PWM引腳位置
串口2位置 雙DPTR選擇 AD轉(zhuǎn)換結(jié)果存放方式調(diào)整 SPI位置調(diào)整
void
ini_T0(void)
{
TMOD=0x02;//T0方式2
TH0=0xb2;
//12MH時
TL0=0xb2;
TR0=1;
}
//
//頻率為50HZ
周期的1/50=0.02s,將0.02S分成256分:0.02/256=0.000078125S=0.078125ms
//0.078125為一份的時間
一共256份
//CCAP0L=223;CCAP0H=223;為2.5ms
//243時約為1ms (0.9375)
//CCAP0L=249;CCAP0H=248;為0.5ms
//236時為1.5ms (1.484375)
//230為2ms (2.03125)
void
main(void)
{
ini_T0();
//方式2,0.078125ms溢出,每溢出一次CL加1
CMOD=0x04;//定時器0溢出率作為時鐘輸入
//CIDL - -
- CPS2 CPS1 CPS0 ECF
//--------------------------------
//CIDL:計數(shù)陣列空閑控制,0時,空閑模式下PCA計數(shù)器繼續(xù)工作;1時空閑模式PCA停止工作。
//----------------------------------------------
//CPS2
CPS1 CPS0: PCA計數(shù)脈沖選擇
//000:系統(tǒng)時鐘,F(xiàn)OSC/12
//001:系統(tǒng)時鐘,F(xiàn)OSC/2
//010:定時器0的溢出,可實現(xiàn)可調(diào)頻率PWM輸出
//011:ECI/P3.4腳的外部時鐘輸入(最大速率FOSC/2)
//100:系統(tǒng)時鐘,FOSC
//101:系統(tǒng)時鐘/4,FOSC/4
//110:系統(tǒng)時鐘/6,FOSC/6
//111:系統(tǒng)時鐘/8,FOSC/8
//-----------------------------------------------
//ECF:PCA計數(shù)溢出中斷使能:1時,使能寄存器CCON CF位的中斷。0時禁止該功能。
CL=0x00;//清零自由遞增計數(shù)的16位定時器的值
CH=0x00;//CH0為00
看結(jié)構(gòu)圖,CL前面是永遠是0
//CCAP0L=223;//裝入比較初值
//CCAP0H=223;
PCA_PWM0=0x00;
//EPC0H=0,EPC0L=0
CCAPM0=0x42;//設(shè)置ECOM1=1,PWM1=1.
//CCAP1L=223;
//CCAP1H=223;
PCA_PWM1=0x00;//EPC1H=0,EPC1L=0
CCAPM1=0x42;//設(shè)置ECOM1=1,PWM1=1.
CR=1;//CR=1,啟動PCA陣列計數(shù)。
看151頁,其中和CMOD的CIDL位有關(guān),又和IDLE有關(guān),看183頁。
//AUXR1=0xc0;//PWM0從P1.3切換到P4.2
//PWM1從P1.4切換到P4.3
while(1)
{
//========================兩舵機停止,中位調(diào)節(jié)用
CCAP0L=236;//裝入比較初值
CCAP0H=236;
CCAP1L=230;//裝入比較初值
CCAP1H=230;
while(1);
}
}
至于怎么調(diào)整pwm的高電平,修改上面CCAPXL和CCAPXH就可以了,這段代碼不是我寫的,但明顯是個高手寫的-
-!至于這段代碼是怎么實現(xiàn)的,程序里的注釋很詳細(xì),小伙伴們在學(xué)了郭天祥的教程以后,嘗試著查看官方的手冊吧,學(xué)習(xí)單片機,重要的不是你學(xué)會了多少多少東西,更重要的還是一種自學(xué)能力,翻手冊,學(xué)這款芯片怎么用的能力。是不是大功告成了呢?并沒有!測試中我發(fā)現(xiàn),CCAPXH和CCAPXL的值每改變1,PWM高電平改變0.07ms左右。那么問題來了,在前面我提到過,360°舵機調(diào)速的區(qū)間,只有0.1ms(1.47-1.37=0.1),這個0.07,是可以讓舵機實現(xiàn)正轉(zhuǎn)反轉(zhuǎn),以及停止,但是沒辦法調(diào)速,循跡小車是需要控制車子兩側(cè)的輪子產(chǎn)生轉(zhuǎn)速差來控制方向的,沒法調(diào)速,就沒法實現(xiàn)循跡。造成這個問題的原因是什么?8位的pwm模塊,8位的pwm,上面程序中的注釋中有這樣一段:
//頻率為50HZ
周期的1/50=0.02s,將0.02S分成256分: 0.02/256=0.000078125S=0.078125ms
//0.078125為一份的時間
一共256份
很清楚了吧!那么是不是51單片機控制不了360°舵機呢?在我制作搬運機器人的過程中,有一段時間我是想過放棄的,但是最終,我發(fā)現(xiàn)了stc15系列單片機,很有意思的是,我在查詢芯片的時候,15這款單片機是沒有pwm模塊的,后來才知道,這款芯片帶有16位的定時器,這樣,問題就迎刃而解了,官方提供的手冊中,有用16位定時器(自動重裝模式)實現(xiàn)8~16位PWM的示例,具體的程序在這里我就不列出來了,在15的手冊100頁,感興趣的小伙伴,自己去看看吧。
好了,360°舵機基本上說完了,其實180°舵機也是相似的,只是高電平的不同代表著不同的角度,0.5ms為0°,2.5為180°。程序都是一樣的。我在這里說下比較容易出現(xiàn)的問題吧。首先,電路上的設(shè)計,舵機要求的電壓為6v-7.2v,你也許會發(fā)現(xiàn)5v其實舵機也能轉(zhuǎn),但是,低電壓會帶來很多未知的問題,比如舵機亂轉(zhuǎn),曾經(jīng)有一段時間,我陷入舵機亂轉(zhuǎn)的怪圈,我以為是我程序的問題,但是示波器顯示沒問題,以至于我以為是舵機壞了。實際上,是電池的問題,電池用的時間長了,電壓不足,讓舵機亂轉(zhuǎn)。所以,電池我建議使用航模sss電池,這個電池是11.2V的,使用降壓模塊,降成7.2v,給舵機供電,將成5v給單片機和傳感器供電就行了。另外,舵機的自己的電路有時候會對單片機有影響,最好加上光耦隔離,防止舵機電路對單片機的干擾。
最后,簡單說下使用舵機驅(qū)動小車和電機相比,有什么優(yōu)劣。首先,就電路而言,由于舵機內(nèi)置有電路,因此我們做機器人設(shè)計電路的時候,僅需要設(shè)計好陰陽極和PWM信號輸入的接口,非常簡單。而普通的減速電機在設(shè)計電路的時候,則需要考慮到驅(qū)動芯片,就比較復(fù)雜了。淘寶上有現(xiàn)成的驅(qū)動模塊,買回來也就直接用了。而在控制上,舵機對于PWM的精度要求也更高,上文中已經(jīng)論述過了。價格方面,舵機的價格是普通減速電機的很多倍,但是昂貴的價格帶來的是拖剎的快速響應(yīng),給定高電平1.5ms的pwm,舵機會立刻剎住以及其充沛的動力這一點是減速電機做不到的。所以到底是采用舵機還是電機,學(xué)弟學(xué)妹自己斟酌吧。
一不留神竟然寫了4000字-
-!可以可以,如果覺得這篇文章不錯,對你有幫助,也歡迎轉(zhuǎn)載啦(請注明本文出處及作者)。我在大一加入了很多組織,最終在機器人協(xié)會找到了落腳點,從最初沒有目的學(xué)習(xí)51單片機,做機器人,到現(xiàn)在有了目標(biāo),學(xué)習(xí)linux,學(xué)習(xí)開發(fā)智能路由器,在這個協(xié)會我還是學(xué)到了很多的東西的。現(xiàn)在呢,其實是以一種感恩的心態(tài),在重復(fù)著往屆學(xué)長學(xué)姐做的事情,很多優(yōu)秀都是一種傳承嘛!也歡迎各位小伙伴加入到重郵基協(xié),加入到我們這個基情四射,整天撕逼的陣營中來吧-
-!我相信在這個良心協(xié)會(真的良心),你會學(xué)習(xí)到你想學(xué)的東西噠!若是對舵機的控制仍有疑問,可以在下方評論留言,我看到會盡快回復(fù)。
重慶郵電大學(xué)機器人協(xié)會
|