新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 用Pic單片機控制8路MG995舵機(servo motor)的實現(xiàn)方法

用Pic單片機控制8路MG995舵機(servo motor)的實現(xiàn)方法

作者: 時間:2016-11-18 來源:網絡 收藏
一個PIC16F877A單片機有1個16位定時器TIMER1,我們用來制8個舵機(即順序脈沖輸出),這樣一個單片機就可以控制8個舵機。用8個IO口來控制舵機,舵機控制的信號周期為20mS,而正脈沖最大只有2.5mS,這樣有17.5mS是空的??梢圆捎眠@種方法:在RD0口輸出一個0.5~2.5mS的脈沖,控制一號舵機。完成后,用端口RD1口輸出另外一個脈沖,控制2號舵機,就這樣下去.....在一號舵機需要第二個脈沖之前,可以輸出 20/2.5=8個脈沖,可以用來控制8個舵機,當然,需要用8個IO口。但是一般來說不可能正好有8個2.5mS的脈沖來填滿20mS,這樣就需要對輸出脈沖的總寬度進行累加補償,然后再用低電平填滿20mS中剩下的時間。一個周期讓timer1工作8~9次,前8次每次根據不同舵機的脈寬要求進行定時,每次都對不同的IO口輸出脈沖.第九個定時是用來填滿20mS的剩余時間的. 每個口在輸完脈沖后,置0 ,然后單片機就不用管他,可以進行下一個IO口的脈沖輸出了. 這樣一個單片機順序對8個IO口進行脈沖輸出. 雖然每個舵機的脈沖時間有一點延遲,但是不超過20mS,這對于舵機這種低速運行器件來說是完全感覺不出來的。仿真如下圖:

本文引用地址:http://m.butianyuan.cn/article/201611/315939.htm

下面就用這種方法進行編程。
#include
unsigned char servo_angle_H[8];
unsigned char servo_angle_L[8];

unsigned char compensate_TL;
unsigned char compensate_TH;

unsigned char p;


void set_servo (unsigned char angle0,unsigned char angle1,
unsigned char angle2,unsigned char angle3,
unsigned char angle4,unsigned char angle5,
unsigned char angle6,unsigned char angle7)
{
unsigned int temp,temp0,value[8];
unsigned char i;

for(i=0;i<8;i++){
servo_angle_H[i]=64468/256;
servo_angle_L[i]=64468%256;
}

compensate_TL=50268%256;
compensate_TH=50268/256;

temp = angle0+angle1+angle2+angle3+angle4+angle5+angle6+angle7;
value[0]=65068-(100*angle0)/9;
value[1]=65068-(100*angle1)/9;
value[2]=65068-(100*angle2)/9;
value[3]=65068-(100*angle3)/9;
value[4]=65068-(100*angle4)/9;
value[5]=65068-(100*angle5)/9;
value[6]=65068-(100*angle6)/9;
value[7]=65068-(100*angle7)/9;
for(i=0;i<8;i++){
servo_angle_H[i]=value[i]/256;
servo_angle_L[i]=value[i]%256;
}

temp0=46068+(100*temp)/9;
compensate_TL=temp0%256;
compensate_TH=temp0/256;

}
//主程序***********************************************************************
void main(void)
{unsigned int a;unsigned int b;
INTCON=0;
GIE=1;//;打開總中斷
PEIE=1;//;打開外部中斷使能位
TMR1IE=1;//;打開TMR1中斷

TRISD=0X00;
PORTD= 0X00;//脈沖波形起始狀態(tài)
T1CON=0x01;//設置TMR1的控制字

TMR1IF=0;

unsigned char i;


set_servo (13,34,56,87,80,123,156,13);
while(1){;}

}
//中斷服務程序*************************************************************
void interrupt timer1(void)
{
TMR1IF=~TMR1IF;

switch(p){
case 0:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0X01;
break;
case 1:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B00000010;
break;
case 2:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B00000100;
break;
case 3:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B00001000;
break;
case 4:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B00010000;
break;
case 5:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B00100000;
break;
case 6:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B01000000;
break;
case 7:TMR1L=servo_angle_L[p];TMR1H=servo_angle_H[p];PORTD=0B10000000;
break;
default:TMR1L=compensate_TL;TMR1H=compensate_TH;PORTD=0B00000000;p=0;
break;
}
p++;
}



評論


技術專區(qū)

關閉