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