|
楼主 |
发表于 2010-5-9 14:07:31
|
显示全部楼层
/********************************
循线小车程序(含碰撞)
芯片:AT89S52 频率:24.576mhz
编写:wjd
********************************/
/*包含头文件*/
#include <reg52.h>
#include <math.h>
/*定义变量*/
unsigned char VL,VR,tt; //全局定义变量:VL,VR为左右电机速度,tt为pwm时间
sbit sp=P0^6;
bit pe; //碰撞标志
bit bd; //倒退后的转向
/*电机控制端*/
sbit MLP=P2^0; //左电机使能
sbit MRP=P2^1; //右电机使能
sbit MLG=P2^2; //左电机前进
sbit MLB=P2^3; //左电机后退
sbit MRG=P2^4; //右电机前进
sbit MRB=P2^5; //右电机后退
/*红外传感器*/
sbit SR2=P0^0; //
sbit SR1=P0^1; //左一和右一在黑线上
sbit SL1=P0^2; //
sbit SL2=P0^3; //
/* 碰撞开关 */
sbit SWR=P1^0;
sbit SWB=P1^1;
sbit SWL=P1^2;
/*************************
电机控制函数
l,r分别为左右电机速度
速度范围:“-9~0~+9”整数
*************************/
void M(int l,r)
{
if(l<0)
{MLG=0;MLB=1;}
else
{
if(l==0)
{MLG=1;MLB=1;l=9;}
else
{MLG=1;MLB=0;}
}
if(r<0)
{MRG=0;MRB=1;}
else
{
if(r==0)
{MRG=1;MRB=1;r=9;}
else
{MRG=1;MRB=0;}
}
VL=abs(l);
VR=abs(r);
}
/*初始化变量和端口*/
void init(void)
{
VL=0;
VR=0;
MLP=1;
MRP=1;
MRG=0;
MLG=0;
MRB=0;
MLB=0;
P3=0xFF;
P0=0xFF;
tt=0;
sp=1;
EX0=1;
IT0=0;
pe=1;
bd=1;
}
/*s设置定时器0用于PWM调速*/
void InitTimer0(void)
{
TMOD = 0x01;
TH0 = 0x0FF;
TL0 = 0x0EC;
EA = 1;
ET0 = 1;
TR0 = 1;
}
/*定时器0中断(PWM)处理 */
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0x0F8;
TL0 = 0x00;
if(tt==9)
{
tt=0;
MLP=1;
MRP=1;
}
else
{
if(VL==tt)MLP=0;
if(VR==tt)MRP=0;
}
tt++;
}
/*毫秒延时*/
void delayms(unsigned int m)
{
for(;m>0;m--)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/*外部中断0(碰撞)*/
void int1() interrupt 0
{
pe=0;
}
/*碰撞时后退*/
void back(void)
{
M(-3,-3);
delayms(100);
if(bd)
{
M(3,-3);
bd=0;
}
else
{
M(-3,3);
bd=1;
}
}
/*碰撞处理*/
void peng(void)
{
if(SWB==0)
{
M(-3,-3);
delayms(300);
M(-3,3);
delayms(200);
while((P0|0xf0)!=0xF9)
{
if(~SWL)M(3,-3);
if(~SWR)M(-3,3);
if(~SWB)back();
}
}
if(SWL==0)
{
M(-3,-3);
delayms(200);
M(3,-3);
delayms(200);
while((P0|0xf0)!=0xF9)
{
if(~SWL)M(3,-3);
if(~SWR)M(-3,3);
if(~SWB)back();
}
}
if(SWR==0)
{
M(-3,-3);
delayms(200);
M(-3,3);
delayms(200);
while((P0|0xf0)!=0xF9)
{
if(~SWL)M(3,-3);
if(~SWR)M(-3,3);
if(~SWB)back();
}
}
pe=1;
}
/*循线控制*/
void follow_line(void)
{
switch(P0|0xf0)
{
case 0xF9:M(5,5);break;
case 0xFF:M(5,5);break;
case 0xFD:
{M(5,1);}
while(SL1&&SR1&&pe)
{M(3,0);}break;
case 0xFB:
{M(1,5);}
while(SL1&&SR1&&pe)
{M(0,3);}break;
case 0xFE:
M(4,-4);
while(SL1&&SR1&&pe)
{M(4,-4);}break;
case 0xF7:
M(-4,4);
while(SL1&&SR1&&pe)
{M(-4,4);}break;
case 0x00:M(0,0);break;
default:M(0,0) ;
}
}
void main() //主函数
{
init();
InitTimer0();
while(1)
{
follow_line();
if(~pe)peng();
/*+其它程序*/
}
} |
|