#include<BoeBot.h>
#include <at89x51.H>
#define uchar unsigned char
#define uint unsigned int
#define backSteps 11
sbit ENABLE = P2^4; //定义ENABLE为P2^4引脚使能位。
sbit RST=P2^4; /*P1_4为P1口的第3位*/ //复位引脚(语音芯片的RST引脚)
sbit CS=P2^1; /*P2_1为P2口的第2位*/ //片选引脚(语音芯片的P02引脚)
sbit SCL=P2^2; /*P2_2为P2口的第3位*/ //时钟引脚(语音芯片的P03引脚)
sbit SDA=P2^0; /*P2_0为P2口的第1位*/ //数据引脚(语音芯片的P01引脚)
bit bReadFlag; //51单片机读取一位数据的标志位。
bit bHeadFlag; //51单片机读玩数据的标志位。
uint code city[28]=
{/*哈尔滨*/200,/*长春*/11474,/*沈阳*/59418,/*大连*/54368,
/*天津*/46465,/*北京*/19858,/*石家庄*/47314,/*太原*/21916,
/*济南*/52447,/*青岛*/49359,/*徐州*/21214,/*郑州*/38912,
/*西安*/38845,/*重庆*/59526,/*武汉*/35858,/*合肥*/11789,
/*南京*/35129,/*蚌埠*/27452,/*上海*/41934,/*杭州*/10574,
/*南昌*/36606,/*长沙*/46380,/*贵阳*/18904,/*广州*/27448,
/*深圳*/59851,/*厦门*/13327,/*福州*/36686,/*宁波*/56310,
};
uchar count;
uchar command[12]; //存储读取的数据。
char angle[35]={-1,-1,10,2,-1,10,2,1, -1,-1,-1,10,10,20,1,-1,-1,-2,10,2,-1,-1,1,1,1,-2,1,1,1,1,-2,10,2, -2,10},number=0;
uchar flags[28]={0,1,0,0,1,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,1,0,0,0,0,1,1,1};
void voice_broadcast(uchar addr); //语音播报函数
uint RFID(void);
void readRFID();
void init_serial(void)
{
TMOD |=0x20;/*定时器1工作于模式2,8位自动重装入定时器*/
TL1=0xf4;/*晶振为11.0592MHz时,设置波特率为2400bps*/
TH1=0xf4;/*晶振为11.0592MHz时,设置波特率为2400bps*/
TR1=1;/*启动定时器1*/
SCON=0x50;/*UART工作于方式1,8位波特率可变串口,允许接收*/
PCON=0x00;/*波特率不加倍*/
EA=1;/*使能总中断*/
ES=1;/*使能串口中断*/
}
void ser() interrupt 4 //串口中断函数
{
uchar ch; //读取变量ch。
ES = 0; //关闭使能串口中断。
if(RI) //如果51单片机读得数据,即RI==1,则执行下面。
{
RI = 0; //将RI置0。
ch = SBUF; //读取数据。
if(ch==0x0a) //如果读取的数据为0x0a,则为数据组的开始位。
{
count=0;
command[count]=ch;
bHeadFlag=1; //收到数据组的开始位,则将标记位bHeadFlag置1。
}
else
{
if(bHeadFlag==1) //如果标记位bHeadFlag为1,则继续接收数据,将数据存入command数组。
{
count++;
command[count]=ch;
if(count==(11)) //如果接收的数据到达11个,将bReadFlag置1,bHeadFlag置0。
{
bReadFlag=1;
bHeadFlag=0;
}
}
}
}
ES=1; //打开使能串口中断。
}
uint RFID(void)
{
uchar i,j; //循环变量i。 h[5],
uint a=0; //变量a存储IC卡的ID。
count=0;
ENABLE=1; //读取IC卡的使能能端置高位,读取设备处于闲置状态。
bReadFlag=0; //初始化bReadFlag和bHeadFlag变量。
bHeadFlag=0;
init_serial(); //中断读卡串口初始化
ENABLE=0; //读取IC卡的使能能端置低位,激活读取设备,开始读取IC卡的信息。
for(j=0;j<20;j++)
{
if(bReadFlag==1) //如果标志位bReadFlag为1,则执行下面。
{
ES=0; //关闭使能串口中断。
a=0; //初始化a。
ENABLE=1; //读取IC卡的使能能端置高位,读取设备处于闲置状态。
for(i=7;i<=10;i++) //提起ID值。
{ //转换
if(command[i]=='0'||command[i]=='1'||command[i]=='2'||command[i]=='3'||command[i]=='4'||command[i]=='5'||command[i]=='6'||command[i]=='7'||command[i]=='8'||command[i]=='9')
{
a=a*16+command[i]-48;
}
else
{
a=a*16+(command[i]-'A')+10;
}
}
bReadFlag=0; //初始化bReadFlag和bHeadFlag变量都为0。
bHeadFlag=0;
break;
}
delay_nms(100);
}
return a;
}
void voice_broadcast(unsigned char addr) //语音播报函数
{
uchar i;
RST=0;
delay_nms(5);
RST=1;
delay_nms(17); /* 17ms*/
CS=0;
delay_nms(2);
for(i=0;i<8;i++)
{
SCL=0;
if(addr & 1)
SDA=1;
else
SDA=0;
addr>>=1;
delay_nms(1); /* 100us */
SCL=1;
delay_nms(1);
}
CS=1;
}
void readRFID()
{
uchar j=0;
uint r;
r=RFID();
for(j=0;j<28;j++)
{
if((r==city[j])&&(flags[j]==0))
{
voice_broadcast(j);
flags[j]=1;
}
}
}
int Get_4QTI_State(void)
{
return P0&0xf0;
}
int Get_4QTI_State2(void)
{
return P0&0x0f;
}
void MoveAStep(int LeftP,int RightP)
{
P1_1=1;
delay_nus(LeftP);
P1_1=0;
P1_0=1;
delay_nus(RightP);
P1_0=0;
delay_nms(20);
}
void Forward(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1650,1300);
for(i=0;i<5;i++)
MoveAStep(1500,1500);
}
void zuo(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1600,1300);
for(i=0;i<5;i++)
MoveAStep(1500,1500);
}
/*void you(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1700,1420);
for(i=0;i<5;i++)
MoveAStep(1500,1500);
}*/
void youzhuan(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1550,1550);
}
/*void zuozhuan(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1450,1450);
}*/
void Backward(int steps)
{
char i;
for(i=0;i<steps;i++)
MoveAStep(1350,1700);
for(i=0;i<5;i++)
MoveAStep(1500,1500);
}
void test()
{
char j;
while(1)
{
if((P0_5==1)&&(P0_6==1))
{
for(j=0;j<5;j++)
MoveAStep(1500,1500);
break;
}
if((P0_5==0)&&(P0_6==1))
while((P0_5!=1)||(P0_6!=1))
{MoveAStep(1425,1425);}
if((P0_5==1)&&(P0_6==0))
while((P0_5!=1)||(P0_6!=1))
{MoveAStep(1575,1575);}
}
}
void test2()
{
char j;
while(1)
{
if((P0_1==1)&&(P0_2==1))
{
for(j=0;j<5;j++)
MoveAStep(1500,1500);
break;
}
if((P0_1==0)&&(P0_2==1))
while((P0_1!=1)||(P0_2!=1))
{MoveAStep(1425,1425);}
if((P0_1==1)&&(P0_2==0))
while((P0_1!=1)||(P0_2!=1))
{MoveAStep(1575,1575);}
}
}
void CrossCity()
{
char i=0,j=0,present_state=0;
while(1)
{
if(((P0_5==1)&&(P0_6==1))||((P0_5==0)&&(P0_6==1))||((P0_5==1)&&(P0_6==0)))
//if(((P0_5==1)&&(P0_6==1)))
{
if(present_state==0)
{
present_state=1;
i++;
}
}
else
present_state=0;
if((i==angle[number])||(i==-angle[number]))
{
//for(j=0;j<5;j++)
// MoveAStep(1500,1500);
test();
break;
}
else
if(angle[number]>0)
{
MoveAStep(1650,1650); //turn right
}
else
{
MoveAStep(1350,1350); //turn left
}
}
}
void CrossCity2()
{
char j=0;
while(1)
{
//if((P0_1==1)&&(P0_2==1))
if(((P0_1==1)&&(P0_2==1))||((P0_1==0)&&(P0_2==1))||((P0_1==1)&&(P0_2==0)))
{
//for(j=0;j<5;j++)
// MoveAStep(1500,1500);
test2();
break;
}
if(angle[number]==10)
MoveAStep(1650,1650);
else
MoveAStep(1350,1350);
}
}
void CrossCity3() //逆时针尾部扫第二根线
{
char i=0,j=0,present_state=0;
number=13;
while(1)
{
//if((P0_1==1)&&(P0_2==1))
if(((P0_1==1)&&(P0_2==1))||((P0_1==0)&&(P0_2==1))||((P0_1==1)&&(P0_2==0)))
{
if(present_state==0)
{
present_state=1;
i++;
}
}
else
present_state=0;
if(i==2)
{
//for(j=0;j<5;j++)
// MoveAStep(1500,1500);
test2();
break;
}
else
MoveAStep(1350,1350);
}
}
void CrossCity4() //顺时针尾部扫第二根线
{
char i=0,j=0,present_state=0;
while(1)
{
//if((P0_1==1)&&(P0_2==1))
if(((P0_1==1)&&(P0_2==1))||((P0_1==0)&&(P0_2==1))||((P0_1==1)&&(P0_2==0)))
{
if(present_state==0)
{
present_state=1;
i++;
}
}
else
present_state=0;
if(i==2)
{
//for(j=0;j<5;j++)
// MoveAStep(1500,1500);
test2();
break;
}
else
MoveAStep(1650,1650);
}
}
void Back_Line(void)
{
int LeftPulse,RightPulse;
while(1)
{
switch(Get_4QTI_State2())
{
case 0x06: LeftPulse=1300;RightPulse=1700;break;
case 0x04: LeftPulse=1300;RightPulse=1600;break;
case 0x02: LeftPulse=1400;RightPulse=1700;break;
case 0x01: LeftPulse=1550;RightPulse=1600;break;
case 0x08: LeftPulse=1400;RightPulse=1450;break;
case 0x03: LeftPulse=1500;RightPulse=1600;break;