舵機:
舵機一般由舵盤、減速齒輪組、位置反饋電位器、直流電機、控制電路板等組成。一般情況下舵機的信號線為黃色或者白色,電源主要常見為4.2-7.4V,不同的供電將直接影響舵機的扭矩標準。
控制方法-PWM :
PWM通過占空比來控制舵機,所謂PWM就是通過程序控制單片機IO口按照一定的時間規律輸出高電平或低電平,具體可以上網查閱資料了解一下。
以下為不同的占空比時間對應的舵機角度:
對于t=0.5 - 2.5ms的產生,寫程序時我們可以采用全局變量。讓全局變量等于525之間,因為舵機的一個計數周期是0.1ms,這樣全局變量的525正好就是0.5~2.5ms
PWM波產生思路:將信號管腳線初始化為低電平,然后寫一個while循環,在循環中將該管腳置為為高電平,延時,再拉低為低電平,如此循環產生PWM波,以高電平產生時間來控制舵機轉動角度。
注意:5mv以上的控制電壓的變化就會引起電機的抖動。
基于單片機的控制:
單片機系統實現對舵機輸出轉角的控制,必須先完成兩個任務:
1、產生PWM周期信號,本設計產生一個20ms的周期信號;
2、脈寬的調整,即單片機模擬PWM信號的輸出,并調整占空比。
當系統中只需要實現一個舵機的控制,采用的控制方式是改變單片機的一個定時器中斷的初值,將20ms分為兩次中斷執行,一次短定時中斷和一次長定時中斷。這樣既節省了硬件電路,也減少了軟件開銷,控制系統工作效率和控制精度都很高。
具體的設計過程:例如想讓舵機轉向左極限的角度,它的正脈沖為2ms,則負脈沖為20ms-2ms=18ms,所以開始時在控制口發送高電平,然后設置定時器在2ms后發生中斷,中斷發生后,在中斷程序里將控制口改為低電平,并將中斷時間改為18ms,再過18ms進入下一次定時中斷,再將控制口改為高電平,并將定時器初值改為2ms,等待下次中斷到來,如此往復實現PWM信號輸出到舵機。用修改定時器中斷初值的方法巧妙形成了脈沖信號,調整時間段的寬度便可使伺服機靈活運動。
為保證軟件在定時中斷里采集其他信號,并且使發生PWM信號的程序不影響中斷程序的運行(如果這些程序所占用時間過長,有可能會發生中斷程序還未結束,下次中斷又到來的后果),所以需要將采集信號的函數放在長定時中斷過程中執行,也就是說每經過兩次中斷執行一次這些程序,執行的周期還是20ms。
如果系統中需要控制幾個舵機的準確轉動,可以用單片機和計數器進行脈沖計數產生PWM信號。
脈沖計數可以利用51單片機的內部計數器來實現,但是從軟件系統的穩定性和程序結構的合理性看,宜使用外部的計數器,還可以提高CPU的工作效率。
下面列舉一個按鍵控制舵機轉動的程序代碼:
#include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
sbit KEY1=P3^4;
//按鍵1
sbit KEY2=P3^5;
//按鍵2
sbit PWM_OUT=P2^7;
//PWM輸出口
uint PWM_Value;
//定義pwm值
uchar order=0;
void Delay(unsigned int s);
//延時函數聲明
uchar flag;
//舵機按鍵標志
/ 延時函數 /
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i
for(i=0; i
}
/ 定時器初始化 /
void Init_Timer0()
{
TMOD=0x11;
TH0=(65536-1500)/256;
TL0=(65536-1500)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
PT0=1;
}
/ 主函數 /
void main(void)
{
Delay(6000);
PWM_Value = 1500;
//pwm初值為1500
Init_Timer0();
while(1)
{
if((KEY1 ==0 )|(KEY2 ==0 ))
//按鍵1或按鍵2被按下
{
if(KEY1 ==0 )
//確認按鍵1被按下
{
flag = 1;
//標志位賦值1
}
if(KEY2 ==0 )
//確認按鍵2被按下
{
flag = 2;
//標志位賦值2
}
}
else
{
flag = 0;
//否則標志位為0
}
Delay(20);
//延時20ms
}
}
/ 中斷程序 **/
void timer0(void) interrupt 1
{
if(flag==1) PWM_Value += 1;
//如果標志位1時,pwm的值加1
if(flag==2) PWM_Value -= 1;
//如果標志位為2時,pwm減1
if(PWM_Value>=2500)
//如果pwm的值大于2500
PWM_Value = 2500;
//則保持在2500
if(PWM_Value<=500)
//如果pwm的值小于500
PWM_Value=500;
//則保持在500
switch(order)
{
case 1:PWM_OUT=1;
TH0=(65536-PWM_Value) > >8;
TL0=(uchar)(65536-PWM_Value);
break;
case 2:PWM_OUT=0;
TH0=(65536-(5000-PWM_Value)) > >8;
TL0=(uchar)(65536-(5000-PWM_Value));
break;
case 3:
TH0=60536 > >8;
TL0=(uchar)60536;
break;
case 4:
TH0=60536 > >8;
TL0=(uchar)60536;
order=0;
break;
default: order=0;
break;
}
order++;
}
-
電位器
+關注
關注
14文章
1012瀏覽量
66767 -
直流電機
+關注
關注
36文章
1710瀏覽量
70157 -
51單片機
+關注
關注
274文章
5702瀏覽量
123494 -
PWM控制
+關注
關注
7文章
194瀏覽量
26280 -
舵機
+關注
關注
17文章
268瀏覽量
41014
發布評論請先 登錄
相關推薦
評論