|
#include<REG52.H>
#define uchar unsigned char
#define uint unsigned int
uint buffer[3];
uint rec_flag=0;
sbit servo0=P2^0;
sbit servo1=P2^1;
sbit servo2=P2^2;
sbit servo3=P2^3;
sbit servo4=P2^4;
sbit servo5=P2^5;
sbit servo6=P2^6;
sbit servo7=P2^7;
uint pwm[]={1382,1382,1382,1382,1382,1382,1382,1382}; //初始90度,(实际是1382.4,取整得1382)
uint pwm_flag=0;
uint code ms0_5Con=461; //0.5ms计数 (实际是460.8,取整得461)
uint code ms2_5Con=2304; //2.5ms计数
/*-----------------------串口初始化----------------------------*/
void UART_Init(void)
{
TMOD = 0x21;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd; //设置波特率 9600
TL1 = 0xFd;
TR1 = 1; //启动定时器1
ES = 1; //开串口中断
EA = 1; //开总中断
IT0=0;
EX0=1;
}
/*------------------------舵机定时器--------------------------*/
void Timer0Init()
{
//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
//2.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=-ms2_5Con>>8; //给定初值,2.5ms中断
TL0=-ms2_5Con;
EA=1; //总中断打开
ET0=1; //定时器0中断打开
TR0=1; //定时器0开关打开
}
/*------------------------角度值转换--------------------------*/
uint Transform(uchar val)
{
//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
//2.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)
//return (uint)(((float)(2/180)*X+0.5)/1000*11059200/12);
uint a = (val+46)*10;
if(a<ms0_5Con)
a=ms0_5Con;
if(a>ms2_5Con)
a=ms2_5Con;
return a;
}
/*-------------------------主函数---------------------------*/
void main(void)
{
UART_Init(); //初始化串口
Timer0Init();//舵机定时初始化
while(1)
{
}
}
/*--------------------串口解析执行-------------------------*/
void Communication_Decode(void)
{
if(buffer[0]==0x00)
{
switch(buffer[1])
{
case 0x01:P1=0xF6; return;
case 0x02:P1=0xF9; return;
case 0x03:P1=0xF5; return;
case 0x04:P1=0xFA; return;
case 0x00:P1=0x00; return;
default: return;
}
}
else if(buffer[0]==0x01)
{
if(buffer[2]>180)
return;
switch(buffer[1])
{
case 0x01:pwm[0]=Transform(buffer[2]); return; //角度值与脉宽计数值转换
case 0x02:pwm[1]=Transform(buffer[2]); return;
case 0x03:pwm[2]=Transform(buffer[2]); return;
case 0x04:pwm[3]=Transform(buffer[2]); return;
case 0x05:pwm[4]=Transform(buffer[2]); return;
case 0x06:pwm[5]=Transform(buffer[2]); return;
case 0x07:pwm[6]=Transform(buffer[2]); return;
case 0x08:pwm[7]=Transform(buffer[2]); return;
default : return;
}
}
else
{
return;
}
}
/*------------------------舵机中断函数--------------------------*/
void SteeringGear() interrupt 1
{
switch(pwm_flag)
{
case 1: servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break;
case 2: servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break;
case 3: servo1=1; TH0=-pwm[1]>>8; TL0=-pwm[1]; break;
case 4: servo1=0; TH0=-(ms2_5Con-pwm[1])>>8; TL0=-(ms2_5Con-pwm[1]); break;
case 5: servo2=1; TH0=-pwm[2]>>8; TL0=-pwm[2]; break;
case 6: servo2=0; TH0=-(ms2_5Con-pwm[2])>>8; TL0=-(ms2_5Con-pwm[2]); break;
case 7: servo3=1; TH0=-pwm[3]>>8; TL0=-pwm[3]; break;
case 8: servo3=0; TH0=-(ms2_5Con-pwm[3])>>8; TL0=-(ms2_5Con-pwm[3]); break;
case 9: servo4=1; TH0=-pwm[4]>>8; TL0=-pwm[4]; break;
case 10: servo4=0; TH0=-(ms2_5Con-pwm[4])>>8; TL0=-(ms2_5Con-pwm[4]); break;
case 11: servo5=1; TH0=-pwm[5]>>8; TL0=-pwm[5]; break;
case 12: servo5=0; TH0=-(ms2_5Con-pwm[5])>>8; TL0=-(ms2_5Con-pwm[5]); break;
case 13: servo6=1; TH0=-pwm[6]>>8; TL0=-pwm[6]; break;
case 14: servo6=0; TH0=-(ms2_5Con-pwm[6])>>8; TL0=-(ms2_5Con-pwm[6]); break;
case 15: servo7=1; TH0=-pwm[7]>>8; TL0=-pwm[7]; break;
case 16: servo7=0; TH0=-(ms2_5Con-pwm[7])>>8; TL0=-(ms2_5Con-pwm[7]); break;
default:TH0=0xff; TL0=0x80; pwm_flag=0;
}
pwm_flag++;
}
/*------------------------串口中断函数--------------------------*/
void INT_UartRcv(void) interrupt 4
{
static int i;
if(RI==1)
{
RI = 0;
if(rec_flag==0)
{
if(SBUF==0xff)
{
rec_flag=1;
i=0;
}
}
else
{
if(SBUF==0xff)
{
rec_flag=0;
if(i==3)
{
Communication_Decode();
}
i=0;
}
else
{
buffer[i]=SBUF;
i++;
}
}
}
else
{
TI = 0;
}
}
这是大帅写的51版8路舵机程序,
我用了2块298,测试后舵机没问题,有时候动了就不停必须得按停,有时候正常,有时候没反应,因为我用的是2个298,所以in1234分别接了P2的8个IO口,所以有时候就只有2个轮子动,我自己改了代码,0xAA,0x55,0x5A,0xA5,0x00,但是改了后居然一点反应都木有。求助啊 |
|