20ms為舵機週期,一個週期可以同時控制8個舵機,20/2.5=8.
用定時器產生脈衝,兩個定時器T0,T1,8*2,同時可以控制16個舵機,
以下是用按鍵控制一個舵機的轉動,你可以參考以下程式,多設個io口,在switch函式中的條件語句中加各個io口脈寬,以下程式中的例如:case0中的if可以多加幾個io控制就可以同時控制多個了,程式前面也可以開定時器T0,以下就只開T1。懶得改以下程式,你參考下就明白了,原理明白就好搞,以下程式很基礎,很簡單明瞭了。
#include
#defineStop0//宏定義,停止
#defineLeft1
//宏定義,左轉
#defineRight2
//宏定義,右轉
sbitControlPort=P1^1;//舵機訊號埠
sbitKeyLeft=P3^2;
//左轉按鍵埠
sbitKeyRight=P3^3;
//右轉按鍵埠
sbitKeyStop=P1^3;
//歸位按鍵埠
unsignedcharTimeOutCounter=0,LeftOrRight=0;//TimeOutCounter:定時器溢位計數
LeftOrRight:舵機左右旋轉標誌
voidInitialTimer()
{
TMOD=0x10;//定時/計數器1工作於方式1
TH1=(65535-87)/256;
//0.1ms
TL1=(65535-87)%256;
EA=1;//開總中斷
ET1=1;//允許定時/計數器1中斷
TR1=1;//啟動定時/計數器1中斷
}
ControlLeftOrRight()//控制舵機函式
if(KeyStop==0)
while(!KeyStop);
//使標誌等於Stop(0),在中斷函式中將用到
LeftOrRight=Stop;
if(KeyLeft==0)
while(!KeyLeft);
//使標誌等於Left(1),在中斷函式中將用到
LeftOrRight=Left;
if(KeyRight==0)
while(!KeyRight);//使標誌等於Right(2),在中斷函式中將用到
LeftOrRight=Right;
main()
//主函式
InitialTimer();
for(;;)
ControlLeftOrRight();
voidTimer1(void)interrupt3//定時器中斷函式
TimeOutCounter++;
switch(LeftOrRight)
case0:
//為0時,舵機歸位,脈寬1.5ms
if(TimeOutCounter
ControlPort=1;
else
ControlPort=0;
break;
case1://為1時,舵機左轉,脈寬1ms(理論值),實際可以除錯得出
case2://為2時,舵機右轉,脈寬2ms(理論值),實際可以除錯得出
default:break;
if(TimeOutCounter==200)
//週期20ms(理論值),比較可靠,最好不要修改
TimeOutCounter=0;
20ms為舵機週期,一個週期可以同時控制8個舵機,20/2.5=8.
用定時器產生脈衝,兩個定時器T0,T1,8*2,同時可以控制16個舵機,
以下是用按鍵控制一個舵機的轉動,你可以參考以下程式,多設個io口,在switch函式中的條件語句中加各個io口脈寬,以下程式中的例如:case0中的if可以多加幾個io控制就可以同時控制多個了,程式前面也可以開定時器T0,以下就只開T1。懶得改以下程式,你參考下就明白了,原理明白就好搞,以下程式很基礎,很簡單明瞭了。
#include
#defineStop0//宏定義,停止
#defineLeft1
//宏定義,左轉
#defineRight2
//宏定義,右轉
sbitControlPort=P1^1;//舵機訊號埠
sbitKeyLeft=P3^2;
//左轉按鍵埠
sbitKeyRight=P3^3;
//右轉按鍵埠
sbitKeyStop=P1^3;
//歸位按鍵埠
unsignedcharTimeOutCounter=0,LeftOrRight=0;//TimeOutCounter:定時器溢位計數
LeftOrRight:舵機左右旋轉標誌
voidInitialTimer()
{
TMOD=0x10;//定時/計數器1工作於方式1
TH1=(65535-87)/256;
//0.1ms
TL1=(65535-87)%256;
EA=1;//開總中斷
ET1=1;//允許定時/計數器1中斷
TR1=1;//啟動定時/計數器1中斷
}
ControlLeftOrRight()//控制舵機函式
{
if(KeyStop==0)
{
while(!KeyStop);
//使標誌等於Stop(0),在中斷函式中將用到
LeftOrRight=Stop;
}
if(KeyLeft==0)
{
while(!KeyLeft);
//使標誌等於Left(1),在中斷函式中將用到
LeftOrRight=Left;
}
if(KeyRight==0)
{
while(!KeyRight);//使標誌等於Right(2),在中斷函式中將用到
LeftOrRight=Right;
}
}
main()
//主函式
{
InitialTimer();
for(;;)
{
ControlLeftOrRight();
}
}
voidTimer1(void)interrupt3//定時器中斷函式
{
TH1=(65535-87)/256;
TL1=(65535-87)%256;
TimeOutCounter++;
switch(LeftOrRight)
{
case0:
//為0時,舵機歸位,脈寬1.5ms
{
if(TimeOutCounter
{
ControlPort=1;
}
else
{
ControlPort=0;
}
break;
}
case1://為1時,舵機左轉,脈寬1ms(理論值),實際可以除錯得出
{
if(TimeOutCounter
{
ControlPort=1;
}
else
{
ControlPort=0;
}
break;
}
case2://為2時,舵機右轉,脈寬2ms(理論值),實際可以除錯得出
{
if(TimeOutCounter
{
ControlPort=1;
}
else
{
ControlPort=0;
}
break;
}
default:break;
}
if(TimeOutCounter==200)
//週期20ms(理論值),比較可靠,最好不要修改
{
TimeOutCounter=0;
}
}