/**********************************************
工程名:可自动循迹、避障、精确定位的智能电动小车
说 明:本设计是基于89C52MCU的智能电动小车,系统
启动后需要设定当前时间,紧接着选择系统模
式-循迹、避障、定位。
循迹模式主要利用红外反射管实现,发射管不
断发出红外,若地面为黑线则接收管接收不到
信号,输出高电平,当小车不在线上后接收管
收到反射光,输出低电平,小车前头及左右各
装一对,当左侧输出低电平时小车右转一定角
度,当右侧输出高电平时小车左转一定角度。
如此循环判断可实现小车循迹功能。
臂章功能大致和循迹功能一致一致,利用前头
的红外收发管,可判断前方是否遇到障碍,若
遇到绕过障碍物继续前行。
定位功能,主要是是根据需要行驶的距离计算
需要行驶的时间。
版 权:付江云 2010年6月10日授予 杨晓梅
************************************************/
#include
//-----以下是小车行驶模模式宏定义--------------//
#define runstop 0x00
#define runhead 0x01
#define runback 0x02
#define runleft 0x03
#define runright 0x04
//-----以下是左右直流电机前进倒退控制口定义----//
sbit runheadL = P0^0;
sbit runheadR = P0^2;
sbit runbackL = P0^1;
sbit runbackR = P0^3;
//----以下是设置键端口定义---------------------//
//sbit INT0 = P3^2;
sbit keyADD = P2^1;
sbit keyDEC = P2^2;
//--以下是传感器输出端及车头左右亮灯端口定义---//
sbit leftled = P0^7;
sbit rightled = P0^4;
sbit leftIR = P0^6;
sbit rightIR = P0^5;
sbit headIR = P2^0;
//--以下是1602液晶显示的控制端口及数据口定义---//
sbit lcdrs = P2^3;
sbit lcdrw = P2^4;
sbit lcden = P2^5;
#define lcd_data P1
//--------以下是预设液晶显示内容---------------//
unsigned char code num[10] = "0123456789";
unsigned char code stunum[16] = " Fujiangyun.com ";
unsigned char code syswait[16] = " Waitting Start!";
unsigned char code sth[16] = "Please Set Hour!";
unsigned char code stm[16] = "Please Set Mine!";
unsigned char code cho[16] = "Please Chose! ";
unsigned char code waitxj[16] = "Waitting XunJi! ";
unsigned char code waitbz[16] = "Waitting BiZhang";
unsigned char code setdwi[16] = "Please Set DWei!";
unsigned char code line1[8] = " 07cm/s.";
unsigned char code line2_1[16] = "XunJi ";
unsigned char code line2_2[16] = "BiZhang ";
unsigned char code line2_3[7] = "DingWi ";
unsigned char code line2_c[2] = "cm";
unsigned char code cbz[16] = "You Chose BZ. ";
unsigned char code cxj[16] = "You Chose XJ. ";
unsigned char code cdw[16] = "You Chose DW. ";
/*******以下是系统需要用到的全局变量,依次是时、分、秒
、定时器中断次数变量、系统标志变量、功能模式标志变量*/
unsigned char hour,mine,sec,tempnum,sysflag,workflag;
unsigned int golong,dingtime;//定位模式下设定行进的距离及时间
void delayms(unsigned int z)//1毫秒延时函数
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=124;y>0;y--);
}
void lcd_write_com(unsigned char com)//液晶写指令函数
{
lcdrw = 0;
lcdrs = 0;
lcd_data = com;
delayms(5);
lcden = 1;
delayms(5);
lcden = 0;
}
void lcd_write_dat(unsigned char dat)//液晶写数据函数
{
lcdrw = 0;
lcdrs = 1;
lcd_data = dat;
delayms(5);
lcden = 1;
delayms(5);
lcden = 0;
}
void lcd_init()//液晶初始化函数
{
lcden = 0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
lcd_write_com(0x80);
}
void runmode(unsigned char mode)//小车行进模式选择函数
{
runheadL = 0;
runbackL = 0;
runheadR = 0;
runbackR = 0;
switch(mode)
{
case runstop: //停止
{
runheadL = 0;
runbackL = 0;
runheadR = 0;
runbackR = 0;
break;
}
case runhead: //前进
{
runheadL = 1;
runheadR = 1;
break;
}
case runback: //后退
{
runbackL = 1;
runbackR = 1;
break;
}
case runleft: //左转
{
runbackL = 1;
runheadR = 1;
break;
}
case runright: //右转
{
runheadL = 1;
runbackR = 1;
break;
}
default :
{
break;
}
}
}
void xunji()//循迹子程序
{
leftled = leftIR;
rightled = rightIR;
if(leftIR==0)
{
runmode(runright);
delayms(10);
}
if(rightIR==0)
{
runmode(runleft);
delayms(10);
}
runmode(runhead);
}
void bizhang()//避障子程序
{
if(headIR==0)
{
runmode(runback);
delayms(500);
runmode(runleft);
delayms(500);
}
runmode(runhead);
}
void dingwei(unsigned int dat)//定位子程序
{
dat = (dat/7)*1000;//秒速为7厘米
runmode(runhead);
delayms(dat);
runmode(runstop);
sysflag = 1;
}
void main()//主函数入口
{
unsigned char i,tempflag;
//--------------以下是系统初始化----------------------//
sysflag = 0;
hour = 23;
mine = 59;
golong = 0;
tempnum = 0;
EA = 1;
EX0 = 0;
ET0 = 1;
TR0 = 0;
PT0 = 1;
TMOD = 0x01;
TH0 = 0x3C;
TL0 = 0x0B0;
//--------------系统初始化结束----------------------//
lcd_init(); //液晶初始化调用
//---显示初始欢迎数据-------------------//
lcd_write_com(0x80);
for(i=0;i<16;i++)
lcd_write_dat(stunum[i]);
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(syswait[i]);
//---显示初始欢迎数据结束---------------//
runmode(runstop);//初始化小车处于停止状态
while(1)
{
if(sysflag==0)//当系统处于状态0时,判断等待按键设置时间
{
if(INT0==0)
{
delayms(5);
if(INT0==0)
{
switch(tempflag)
{
case 0:
tempflag = 1;
lcd_write_com(0x80);
lcd_write_dat(num[hour/10]);
lcd_write_dat(num[hour%10]);
lcd_write_dat(':');
lcd_write_dat(num[mine/10]);
lcd_write_dat(num[mine%10]);
for(i=0;i<11;i++)
lcd_write_dat(' ');
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(sth[i]);
break;
case 1:
tempflag = 2;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(stm[i]);
break;
case 2:
TR0 = 1;
tempflag = 0;
sysflag = 1;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cho[i]);
break;
default :
break;
}
while(!INT0);
}
}
if(keyADD==0)
{
delayms(5);
if(keyADD==0)
{
switch(tempflag)
{
case 1:
{
if(hour==23)
hour = 0;
else
hour++;
lcd_write_com(0x80);
lcd_write_dat(num[hour/10]);
lcd_write_dat(num[hour%10]);
break;
}
case 2:
{
if(mine==59)
mine = 0;
else
mine++;
lcd_write_com(0x80+3);
lcd_write_dat(num[mine/10]);
lcd_write_dat(num[mine%10]);
break;
}
default :
break;
}
}
while(!keyADD);
}
if(keyDEC==0)
{
delayms(5);
if(keyDEC==0)
{
switch(tempflag)
{
case 1:
{
if(hour==0)
hour = 23;
else
hour--;
lcd_write_com(0x80);
lcd_write_dat(num[hour/10]);
lcd_write_dat(num[hour%10]);
break;
}
case 2:
{
if(mine==0)
mine = 59;
else
mine--;
lcd_write_com(0x80+3);
lcd_write_dat(num[mine/10]);
lcd_write_dat(num[mine%10]);
break;
}
default :
break;
}
}
while(!keyDEC);
}
}
if(sysflag==1)//系统处于状态1时等待选择功能模式
{
if(INT0==0)
{
delayms(5);
if(INT0==0)
{
if(workflag!=0)
{
sysflag = 2;
lcd_write_com(0x80+5);
for(i=0;i<8;i++)
lcd_write_dat(line1[i]);
switch(workflag)
{
case 1:
{
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(waitxj[i]);
break;
}
case 2:
{
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(setdwi[i]);
break;
}
case 3:
{
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(waitbz[i]);
break;
}
default :
break;
}
}
}
while(!INT0);
}
if(keyADD==0)
{
delayms(5);
if(keyADD==0)
{
switch(workflag)
{
case 0:
{
workflag = 1;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cxj[i]);
break;
}
case 1:
{
workflag = 2;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cdw[i]);
break;
}
case 2:
{
workflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cbz[i]);
break;
}
case 3:
{
workflag = 1;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cxj[i]);
break;
}
default :
break;
}
}
while(!keyADD);
}
if(keyDEC==0)
{
delayms(5);
if(keyDEC==0)
{
switch(workflag)
{
case 0:
{
workflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cbz[i]);
break;
}
case 1:
{
workflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cbz[i]);
break;
}
case 2:
{
workflag = 1;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cxj[i]);
break;
}
case 3:
{
workflag = 2;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cdw[i]);
break;
}
}
}
while(!keyDEC);
}
}
if(sysflag==2)//系统处于状态2时等待设置并启动相应的功能模式
{
if(workflag==1)
{
if(INT0==0)
{
delayms(5);
if(INT0==0)
{
sysflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(line2_1[i]);
EX0 = 1;
}
while(!INT0);
}
}
if(workflag==3)
{
if(INT0==0)
{
delayms(5);
if(INT0==0)
{
sysflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(line2_2[i]);
EX0 = 1;
}
while(!INT0);
}
}
if(workflag==2)
{
if(INT0==0)
{
delayms(5);
if(INT0==0)
{
sysflag = 3;
lcd_write_com(0x80+0x40);
for(i=0;i<7;i++)
lcd_write_dat(line2_3[i]);
lcd_write_dat(num[(golong/100)%10]);
lcd_write_dat(num[(golong/10)%10]);
lcd_write_dat(num[golong%10]);
lcd_write_dat('c');
lcd_write_dat('m');
for(i=0;i<4;i++)
lcd_write_dat(' ');
EX0 = 1;
}
while(!INT0);
}
if(keyADD==0)
{
delayms(5);
if(keyADD==0)
{
if(golong==990)
golong = 0;
else
golong = golong+10;
lcd_write_com(0x80+0x40);
lcd_write_dat(num[(golong/100)%10]);
lcd_write_dat(num[(golong/10)%10]);
lcd_write_dat(num[golong%10]);
for(i=0;i<13;i++)
lcd_write_dat(' ');
}
while(!keyADD);
}
if(keyDEC==0)
{
delayms(5);
if(keyDEC==0)
{
if(golong==0)
golong = 990;
else
golong = golong-10;
lcd_write_com(0x80+0x40);
lcd_write_dat(num[(golong/100)%10]);
lcd_write_dat(num[(golong/10)%10]);
lcd_write_dat(num[golong%10]);
for(i=0;i<13;i++)
lcd_write_dat(' ');
}
while(!keyDEC);
}
}
}
if(sysflag==3) ///系统处于状态3时进行相应的功能模式
{
switch(workflag)
{
case 1:
xunji();
break;
case 2:
dingwei(golong);
break;
case 3:
bizhang();
break;
default :
break;
}
}
}
}
void intt0() interrupt 0
{
unsigned char i;
EX0 = 0;
runmode(runstop);
leftled = 1;
rightled = 1;
delayms(5);
sysflag = 1;
lcd_write_com(0x80+0x40);
for(i=0;i<16;i++)
lcd_write_dat(cho[i]);
while(!INT0);
}
void intt1() interrupt 1 //定时器T0中断函数,用于实时显示
{
TH0 = 0x3C;
TL0 = 0x0B0;
if(tempnum==11)
{
tempnum = 0;
if(sec==59)
{
sec = 0;
if(mine==59)
{
mine = 0;
lcd_write_com(0x80);
lcd_write_dat(num[hour/10]);
lcd_write_dat(num[hour%10]);
lcd_write_dat(':');
lcd_write_dat(num[mine/10]);
lcd_write_dat(num[mine%10]);
if(hour==23)
{
hour = 0;
}
else
hour++;
}
else
{
mine++;
lcd_write_com(0x80);
lcd_write_dat(num[hour/10]);
lcd_write_dat(num[hour%10]);
lcd_write_dat(':');
lcd_write_dat(num[mine/10]);
lcd_write_dat(num[mine%10]);
}
}
else
sec++;
}
else
tempnum++;
}
智能电动小车
《 “智能电动小车” 》 有 2 条评论
-
博主也是学电子的么
-
嗯,呵呵,对啊.
-
发表回复