找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7254|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

關(guān)于51單片機控制舵機(減速電機類似)的詳解

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:105323 發(fā)表于 2016-2-23 22:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
關(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é)會
             
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:130713 發(fā)表于 2016-10-15 12:32 | 只看該作者
可以,很詳細(xì)
回復(fù)

使用道具 舉報

板凳
ID:231115 發(fā)表于 2017-9-9 22:37 | 只看該作者
謝謝,學(xué)習(xí)的好資料
回復(fù)

使用道具 舉報

地板
ID:248544 發(fā)表于 2018-6-14 19:06 | 只看該作者
很有幫助
回復(fù)

使用道具 舉報

5#
ID:223274 發(fā)表于 2019-4-30 11:27 | 只看該作者
資料還不錯哦
回復(fù)

使用道具 舉報

6#
ID:893947 發(fā)表于 2021-3-19 19:38 | 只看該作者
感謝樓主,我最近在琢磨怎么用80c52控制舵機,程序沒問題,試了好幾天都不行,看到這個解答真的是茅塞頓開
回復(fù)

使用道具 舉報

7#
ID:584041 發(fā)表于 2021-5-8 21:39 | 只看該作者
我糾正一下,舵機都是可以調(diào)速的,我以前用ARDUINO控制舵機,讓它一度一度地轉(zhuǎn)動,每度之間的延時達到了控制速度的目的。只是說這樣的編程方式轉(zhuǎn)換到51單片機可能有難度,但是一定行的,所以舵機是可以調(diào)速的。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表