红外探头只工作一次,就是按刚开始检测到的黑线来算,然后只能前进或者右转左转,电机一直保持这种状态,不能按照黑线方向来改变运动状态
#include "reg52.h"
#include <intrins.h>
sbit IN1=P1^0; //定义驱动模块IN1为P1.0 左上电机 M2 OUT1 OUT2
sbit IN2=P1^1; //定义驱动模块IN2为P1.1
sbit IN3=P1^2; //定义驱动模块IN3为P1.2 左下电机 M3 OUT3 OUT4
sbit IN4=P1^3; //定义驱动模块IN4为P1.3
sbit IN5=P1^4; //定义驱动模块IN5为P1.4 右上电机 M1 OUT5 OUT6
sbit IN6=P1^5; //定义驱动模块IN6为P1.5
sbit IN7=P1^6; //定义驱动模块IN7为P1.6 右下电机 M4 OUT7 OUT8
sbit IN8=P1^7; //定义驱动模块IN8为P1.7
sbit left_led=P2^5; //定义左路寻迹为P2.5
sbit middle_led=P2^6; //定义中路寻迹为P2.6
sbit right_led=P2^7; //定义右路寻迹为P2.7
#define Left_moto_go {IN1=1,IN2=0,IN3=1,IN4=0;} //左边两个电机向前走
#define Left_moto_back {IN1=0,IN2=1,IN3=0,IN4=1;} //左边两个电机向后转
#define Left_moto_Stop {IN1=0,IN2=0,IN3=0,IN4=0;} //左边两个电机停转
#define Right_moto_go {IN5=1,IN6=0,IN7=1,IN8=0;} //右边两个电机向前走
#define Right_moto_back {IN5=0,IN6=1,IN7=0,IN8=1;} //右边两个电机向后转
#define Right_moto_Stop {IN5=0,IN6=0,IN7=0,IN8=0;} //右边两个电机停转
bit Right_moto_stop=1;
bit Left_moto_stop =1;
sbit IRIN=P3^2;//红外接收器为P3.2
#define Imax 14000 //晶振位11.0592时的值 (12÷11.0592)*13≈14ms
#define Imin 8000 // 8毫秒
#define Inum1 1450 //
#define Inum2 700
#define Inum3 3000
unsigned char f=0;
unsigned char Im[4]={0x00,0x00,0x00,0x00};
unsigned char show[2]={0,0};
unsigned long m,Tc;
unsigned char IrOK;
//延时函数
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<2000;y++);
}
//接收头解码
void intersvr0(void) interrupt 1 using 1 //定时器T0
{
Tc=TH0*256+TL0; //提取中断时间间隔时长
TH0=0;
TL0=0; //定时中断重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
f=1;
return;
} //找到启始码
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取码
}
if(m==32) //接收完32位数据 用户码/用户反码/数据码/数据反码
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
IrOK=1; //拉高红外接收头电平
}
else IrOK=0; //取码完成后判断读码是否正确
}
//准备读下一码
}
}
//前进函数
void run(void)
{
Left_moto_go ; //左电机往前走
Right_moto_go ; //右电机往前走
}
//后退函数
void backrun(void)
{
Left_moto_back ; //左电机往后走
Right_moto_back ; //右电机往后走
}
//左转函数
void leftrun(void)
{
Left_moto_Stop ; //左电机往后走
Right_moto_go ; //右电机往前走
}
//右转函数
void rightrun(void)
{
Left_moto_go ; //左电机往前走
Right_moto_Stop ; //右电机往后走
}
//小车停止
void stop(void)
{
Left_moto_Stop ; //左电机往前走
Right_moto_Stop ; //右电机往前走
}
void xunji(void)
{
if(right_led==1&&middle_led==1&&left_led==1) //三路检测到黑线
{
run();//前进
}
else
{
if(right_led==1&&middle_led==0&&left_led==0) //右边检测到黑线
{
rightrun();//右转
}
if(right_led==0&&middle_led==0&&left_led==1) //左边检测到黑线
{
leftrun();//左转
}
}
}
//主函数
void main(void)
{
m=0;
f=0;
IT0=1;
EX0=1;
TMOD=0x11;//工作方式3
TH0=0;
TL0=0;
TR0=1;
EA=1; //总中断打开
delay(100);
while(1) /*无限循环*/
{
if(IrOK==1) //判断接收头是否为1
{
switch(Im[2])
{
case 0x18: run(); //前进
break;
case 0x52: backrun(); //后退
break;
case 0x08: leftrun(); //左转
break;
case 0x5A: rightrun(); //右转
break;
case 0x1C: stop(); //停止
break;
case 0x55:xunji (); //寻迹
break;
default:break;
}
IrOK=0;
}
}
}
|